# -*- coding:utf8 -*-
import json
import traceback
import os
import re
import typing
import base64
import time
import pyssdb
import ddddocr
import requests
import binascii
from Crypto.Cipher import AES, DES
from Crypto.Util.Padding import unpad, pad
from lxml import etree
import xml.etree.ElementTree as ET
from datetime import datetime
from urllib.parse import urlparse
from urllib.parse import quote
from scrapy import Request, FormRequest
from .sign_chrome import SignChrome
from .password_encrypt import *
from squirrel_core.commons.utils.get_config import get_config
from squirrel_core.commons.utils.tools import calc_str_md5, upload_file
from squirrel_core.frame.spider_makaka import MakakaSpider

file_path = os.environ.get("FILE_PATH", "/")


class signup_raceno(MakakaSpider):
    name = "signup_raceno"
    headers = {
        "Content-Type": "multipart/form-data; boundary=----WebKitFormBoundaryw5lBv8ld8DimAAxW",
    }
    ht_header = {
        "Host": "rqs.racetigertiming.com",
        "Content-Type": "application/x-www-form-urlencoded",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36",
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7"
    }
    specific_settings = {
        'CONCURRENT_REQUESTS': 100
    }
    return_flag = True
    serialNumber = ""
    home_url = ""
    race_id = ""
    race_name = ""
    phone = ""
    pwd = ""
    user_list = []
    retry_time = 3
    base_config = get_config(sections="base")
    ssdb_host = base_config.get('ssdb_host')
    ssdb_port = base_config.get('ssdb_port')

    shuzixindong_dict = {
        "2025中国银行北京马拉松": "1000284173",
        "2025蚌埠马拉松": "1000322005",
        "2025扬州高邮大运河半程马拉松": "1000316001",
        "2025马鞍山·采石矶半程马拉松": "1000285117",
        "2025滁州马拉松": "1000332055",
        "2025池州马拉松": "1000284080",
        "2025三门峡马拉松": "1000195002",
        "2025淮南马拉松": "1000285154",
        "德文厦门工学院马拉松2025秋季赛 亲子跑&五公里环校跑": "1000285174",
        "2025厦门国际银行中国田径协会10公里精英赛(厦门·翔安站)": "1000349016",
        "2025中国-东盟马拉松": "1000290122"
    }
    malamala_dict = {
        "2025中国银行北京马拉松": "8315065509895961",
        "2025平谷桃花半程马拉松暨2025“首发承平京平杯”平谷半程马拉松": "8535657681101933"
    }

    def get_ext_requests_or_urls(self, data=None):
        if data and isinstance(data, str):
            data = json.loads(data)
        if data and isinstance(data, typing.MutableMapping):
            self.home_url = data.get("url", "")
            self.race_id = data.get("race_id", "")
            self.phone = data.get("phone", "13981808836")
            self.pwd = data.get("password", "aa123456")
            self.serialNumber = data.get("task_id", "")
            self.race_name = data.get("race_name", "").replace(" ", "")
            self.user_list = sorted(data.get("user_list", []), key=lambda x: int(x['priority_level']), reverse=True)
            if not all([self.home_url, self.race_id, self.race_name, self.user_list]):
                self.logger.info("参数不全，请仔细核对")
                self.upload_procedure({"race_id": self.race_id, "code": 203, "message": "参数不全，请仔细核对"})
                self.close_after_idle = True
                self.force_to_close_spider = True
            else:
                self.upload_procedure({"race_id": self.race_id, "code": 200, "message": "任务启动成功"})
                if "rqs.racetigertiming.com" in self.home_url:
                    yield Request(url=self.home_url, callback=self.parse_haituo, dont_filter=True, errback=self.err_parse,
                                  headers=self.ht_header)
                elif "#小程序://无忧赛事" in self.home_url:
                    for user in self.user_list:
                        serial_number = user.get("serialNumber", "")
                        name = user.get("name", "")
                        user_id = user.get("user_id", "")
                        card_num = user.get("card_num", "")
                        priority = int(user.get("priority_level", 0))
                        url = f"https://api.51race.com/wx/race/searchapply?name={card_num}"
                        yield Request(url=url, callback=self.parse_51race, dont_filter=True, errback=self.err_parse,
                                      priority=priority, meta={"user_id": user_id, "card_num": card_num,
                                                               "name": name, "serial_number": serial_number})
                elif "#小程序://柴古唐斯" in self.home_url:
                    game_dict = {
                        "2025柴古唐斯括苍越野赛": "1959293723016257538"
                    }
                    game_id = game_dict.get(self.race_name, "")
                    for user in self.user_list:
                        serial_number = user.get("serialNumber", "")
                        name = user.get("name", "")
                        user_id = user.get("user_id", "")
                        card_num = user.get("card_num", "")
                        priority = int(user.get("priority_level", 0))
                        url = f"https://api.tsaigu.com/chaigu/phone/player/search?keyword={name}&gameId={game_id}&current=1&size=10&searchCount=false"
                        yield Request(url=url, callback=self.parse_cgts, dont_filter=True, errback=self.err_parse,
                                      priority=priority, meta={"user_id": user_id, "card_num": card_num,
                                                               "name": name, "serial_number": serial_number})
                elif "#小程序://去撒野" in self.home_url:
                    token_dict = {
                        "北京三峰之巅越野赛": "b6c93a9e-8ee0-4046-9686-d0fabba81df3"
                    }
                    token = token_dict.get(self.race_name, "")
                    for user in self.user_list:
                        serial_number = user.get("serialNumber", "")
                        name = user.get("name", "")
                        user_id = user.get("user_id", "")
                        card_num = user.get("card_num", "")
                        priority = int(user.get("priority_level", 0))
                        url = "https://qsy.ucs-intertech.com/index.php/api/ygame/result/search"
                        header = {
                            "Host": "qsy.ucs-intertech.com",
                            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x6309092b)XWEB/14315",
                            "token": token,
                            "Content-Type": "application/x-www-form-urlencoded",
                            "Accept": "*/*"
                        }
                        post_data = {"name": name, "idcard": card_num}
                        yield FormRequest(url=url, callback=self.parse_saye, dont_filter=True, errback=self.err_parse,
                                          formdata=post_data, headers=header,
                                          priority=priority, meta={"user_id": user_id, "card_num": card_num,
                                                                   "name": name, "serial_number": serial_number})
                elif "#小程序://赛客助手" in self.home_url or "timer.geexek.com" in self.home_url:
                    cmpt_id = ""
                    if "2025凯乐石东北100松花湖跑山赛" in self.race_name:
                        cmpt_id = "29398"
                    elif "FUGA训练赛" in self.race_name:
                        cmpt_id = "29613"
                    elif "2025云南九大高原湖泊山水联赛抚仙湖站" in self.race_name:
                        cmpt_id = "28603"
                    elif "2025凯乐石贡嘎100冰川极限挑战赛" in self.race_name:
                        cmpt_id = "29653"
                    elif "2025UTO助力首百汤山越野赛" in self.race_name:
                        cmpt_id = "30146"
                    elif "2025四川省“最美绿道”系列赛阆中古城站" in self.race_name:
                        cmpt_id = "30180"
                    elif "2025中江半程马拉松" in self.race_name:
                        cmpt_id = "30127"
                    elif "2025凯乐石莫干山跑山赛" in self.race_name:
                        cmpt_id = "30092"
                    elif "2025南充嘉陵江马拉松" in self.race_name:
                        cmpt_id = "30187"
                    elif "2025重庆垫江明月山越野赛" in self.race_name:
                        cmpt_id = "30367"
                    elif "2025重庆江津东方爱情马拉松" in self.race_name:
                        cmpt_id = "30331"
                    elif "2025户外特工西宏168·寻秋徽州山径探索" in self.race_name:
                        cmpt_id = "30434"
                    elif "2025上海长滩半程马拉松" in self.race_name:
                        cmpt_id = "30451"
                    elif "2025广东从化一百超级越野赛" in self.race_name:
                        cmpt_id = "29494"
                    elif "2025重庆璧山马拉松" in self.race_name:
                        cmpt_id = "30505"
                    elif "第十届戴村山地越野赛" in self.race_name:
                        cmpt_id = "30475"
                    elif "“战马能量”2025年四川省崇州市第八届无根山越野赛" in self.race_name:
                        cmpt_id = "30628"
                    elif "2025重庆忠县马拉松暨第八届长江三峡马拉松" in self.race_name:
                        cmpt_id = "30598"
                    elif "2025贵州·黔南“世遗荔波”小七孔森氧穿越跑" in self.race_name:
                        cmpt_id = "30614"
                    for user in self.user_list:
                        serial_number = user.get("serialNumber", "")
                        name = user.get("name", "")
                        user_id = user.get("user_id", "")
                        card_num = user.get("card_num", "")
                        priority = int(user.get("priority_level", 0))
                        url = f"https://timerbackend.geexek.com/getCertificatesURL.do?cmptId={cmpt_id}&keyword={card_num}"
                        yield Request(url=url, callback=self.parse_pic, dont_filter=True,
                                      errback=self.err_parse, priority=priority,
                                      meta={"user_id": user_id, "card_num": card_num,
                                            "name": name, "serial_number": serial_number})
                elif "marathon.chinaath.com" in self.home_url or "marathon.shuzixindong.com" in self.home_url or "registration-search" in self.home_url:
                    domain = urlparse(self.home_url).netloc
                    url = f"https://api-changzheng.chinaath.com/changzheng-website-center-api/api/official/website/domain/name/selectByDomainName?domainName={domain}"
                    for user in self.user_list:
                        serial_number = user.get("serialNumber", "")
                        name = user.get("name", "")
                        user_id = user.get("user_id", "")
                        card_num = user.get("card_num", "")
                        priority = int(user.get("priority_level", 0))
                        yield Request(url=url, callback=self.parse_hrb, dont_filter=True, errback=self.err_parse,
                                      priority=priority,
                                      meta={"user_id": user_id, "card_num": card_num,
                                            "name": name, "serial_number": serial_number, "domain": domain})
                elif "www.marathon" in self.home_url and "chk_sign_up" in self.home_url:
                    for user in self.user_list:
                        serial_number = user.get("serialNumber", "")
                        name = user.get("name", "")
                        user_id = user.get("user_id", "")
                        card_num = user.get("card_num", "")
                        priority = int(user.get("priority_level", 0))
                        yield Request(url=self.home_url, callback=self.parse_marathon, dont_filter=True, errback=self.err_parse,
                                      priority=priority,
                                      meta={"user_id": user_id, "card_num": card_num,
                                            "name": name, "serial_number": serial_number})
                elif "#小程序://飞翔赛事" in self.home_url or "#小程序://蓦然体育" in self.home_url:
                    if "2025卡游义乌半程马拉松" == self.race_name:
                        app_id = "wxf2812ae0aa198a12"
                        systemid = "200648472"
                        userid = 726829263
                        paramobjid = 712449185
                    if "2025井冈山马拉松" == self.race_name:
                        app_id = "wx755f97a86ccdb646"
                        systemid = "574793229"
                        userid = 726406922
                        paramobjid = 714341301
                    des_key = f"ts.appid.{app_id}"
                    header = {
                        "Host": "moran.zjim.org",
                        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x63090a13) UnifiedPCWindowsWechat(0xf2541022) XWEB/16467",
                        "xweb_xhr": "1",
                        "Content-Type": "application/json",
                        "Accept": "*/*"
                    }
                    for user in self.user_list:
                        serial_number = user.get("serialNumber", "")
                        name = user.get("name", "")
                        user_id = user.get("user_id", "")
                        card_num = user.get("card_num", "")
                        priority = int(user.get("priority_level", 0))
                        post_data = {"appid": app_id, "systemid": systemid, "userid": userid,
                                     "ver": "3.9.11.7", "env": "release", "channel": "", "paramobjid": paramobjid,
                                     "paramval1": card_num}
                        key_str = self.encryptDes(des_key, json.dumps(post_data))
                        _post_data = {"appid": app_id, "text": key_str}
                        url = "https://moran.zjim.org/api/routepost/signupinquiry/match"
                        yield Request(url=url, callback=self.parse_moran, dont_filter=True, errback=self.err_parse,
                                      headers=header, body=json.dumps(_post_data), method="POST",
                                      priority=priority, meta={"user_id": user_id, "card_num": card_num, "des_key": des_key,
                                                               "name": name, "serial_number": serial_number,
                                                               "app_id": app_id, "post_data": post_data, "header": header})
                elif "#小程序://赛中赛" in self.home_url:
                    for user in self.user_list:
                        serial_number = user.get("serialNumber", "")
                        name = user.get("name", "")
                        user_id = user.get("user_id", "")
                        card_num = user.get("card_num", "")
                        priority = int(user.get("priority_level", 0))
                        url = "https://zhongsai-sport.com/prod-api//game/event/registry/player/wx/idnum"
                        header = {
                            "Host": "zhongsai-sport.com",
                            "Authorization": "Bearer eyJhbGciOiJIUzUxMiJ9.eyJ1c2VyX2lkIjoxNDIzOTUsInVzZXJfa2V5IjoiZjQyZDk3MjktMWIzMC00ZTUzLWI3ZDgtZmFiMThlYTBjODgxIiwidXNlcm5hbWUiOiJvZmF3VzdhOUZYaHdYdGp1UU9qWGdBcHJrN1UwIn0.I4C22lQwvbUI6ppWTxsZnGpaommAuQA9lfvti1zoUlmO9Xv7Jd8LkoHRn9GhkeRFqlExYagmmj-YPWRhcbonsQ",
                            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x63090a13) UnifiedPCWindowsWechat(0xf2541022) XWEB/16467",
                            "Content-Type": "application/json",
                            "Accept": "*/*"
                        }
                        post_data = {"idNum": card_num, "gameId": "45"}
                        yield Request(url=url, callback=self.parse_saizhongsai, dont_filter=True, errback=self.err_parse,
                                      priority=priority, body=json.dumps(post_data), headers=header, method="POST",
                                      meta={"user_id": user_id, "name": name, "serial_number": serial_number})
                elif "registration.mararun.com" in self.home_url:
                    url = "https://saas-user-gw.mararun.com/v1/captcha/code"
                    for user in self.user_list:
                        serial_number = user.get("serialNumber", "")
                        name = user.get("name", "")
                        user_id = user.get("user_id", "")
                        card_num = user.get("card_num", "")
                        priority = int(user.get("priority_level", 0))
                        yield Request(url=url, callback=self.parse_shenyang, dont_filter=True, errback=self.err_parse,
                                      headers={"Accept": "application/json, text/plain, */*"}, priority=priority,
                                      meta={"user_id": user_id, "card_num": card_num,
                                            "name": name, "serial_number": serial_number})
                elif "#小程序://糙场" in self.home_url:
                    for user in self.user_list:
                        serial_number = user.get("serialNumber", "")
                        name = user.get("name", "")
                        user_id = user.get("user_id", "")
                        card_num = user.get("card_num", "")
                        priority = int(user.get("priority_level", 0))
                        url = f"https://api.amoysport.cn/weapp/v4/activity/certs?id=1512&type=join&num={card_num}"
                        yield Request(url=url, callback=self.parse_caochang, dont_filter=True, errback=self.err_parse,
                                      headers={"Accept": "application/json, text/plain, */*"}, priority=priority,
                                      meta={"user_id": user_id, "card_num": card_num,
                                            "name": name, "serial_number": serial_number})
                elif "www.xhrace.com" in self.home_url:
                    event_id = "".join(re.findall(r"eventId=(.*?)&", self.home_url))
                    url = f"https://www.xhrace.com/api/statistics/front/getEvent/{event_id}"
                    header = {
                        "Host": "www.xhrace.com",
                        "Accept": "application/json, text/plain, */*",
                        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"
                    }
                    yield Request(url=url, callback=self.parse_xhrace, dont_filter=True, errback=self.err_parse,
                                  headers=header, meta={"event_id": event_id, "header": header})
                elif "#小程序://微步计时" in self.home_url or "sport.luojiweiye.com" in self.home_url:
                    game_id = ""
                    if "sport.luojiweiye.com" in self.home_url:
                        game_id = "".join(re.findall(r"game_id=(\d+)", self.home_url)).strip()
                    else:
                        if "2025崇礼云顶跑山赛" in self.race_name:
                            game_id = "4693"
                        elif "2025莱州" in self.race_name:
                            game_id = "4511"
                        elif "2025云南凤庆滇红越野赛" in self.race_name:
                            game_id = "4419"
                        elif "2025猛犸象熊猫超级山径赛" in self.race_name:
                            game_id = "4522"
                        elif "2025丹棱·老峨山山径赛" in self.race_name:
                            game_id = "4539"
                        elif "西郊四大望越野赛" in self.race_name:
                            game_id = "4741"
                        elif "2025放野大会·天堂寨穿越赛" in self.race_name:
                            game_id = "4801"
                    for user in self.user_list:
                        serial_number = user.get("serialNumber", "")
                        name = user.get("name", "")
                        user_id = user.get("user_id", "")
                        card_num = user.get("card_num", "")
                        priority = int(user.get("priority_level", 0))
                        url = f"https://sport.luojiweiye.com/api/signup/sign_list?game_id={game_id}&name={card_num}&page_size=50&page=1&app_id=wx924e0b1059481b25&appid=wx924e0b1059481b25&api_token=2j8MtqUoEVUQvZrtSJSBVch4nPrBM9eUwwwyXwlCrm5XGlalpD"

                        yield Request(url=url, callback=self.parse_weibu, dont_filter=True,
                                      errback=self.err_parse, priority=priority,
                                      meta={"user_id": user_id, "card_num": card_num,
                                            "name": name, "serial_number": serial_number})
                elif "#小程序://TNF100" in self.home_url or "#小程序://参赛助手" in self.home_url or "西安马拉松" in self.race_name:
                    url = "https://api.ihuipao.com/game/runner/byidnum"
                    if "西安马拉松" in self.race_name or "环蠡湖" in self.race_name or "江阴时裳新桥" in self.race_name or "2025光谷马拉松" in self.race_name or "2025南京银行南京马拉松" in self.race_name:
                        url = "https://api.ihuipao.com/registration/query"
                    header = {
                        "Host": "api.ihuipao.com",
                        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x63090a13) UnifiedPCWindowsWechat(0xf2541022) XWEB/16467",
                        "Accept": "application/json",
                        "Content-Type": "application/json"
                    }
                    for user in self.user_list:
                        serial_number = user.get("serialNumber", "")
                        name = user.get("name", "")
                        user_id = user.get("user_id", "")
                        card_num = user.get("card_num", "")
                        priority = int(user.get("priority_level", 0))
                        if "西安马拉松" in self.race_name:
                            post_data = {"raceid": "KgZdPzQmJydW0XNMnoOJ", "idnum": card_num, "app": "xian",
                                         "_token": "UeHRDkk7T72cf19cjupxe4nUPJEPUxEKcxJbxLAW"}
                        elif "环蠡湖" in self.race_name or "江阴时裳新桥" in self.race_name or "2025光谷马拉松" in self.race_name or "2025南京银行南京马拉松" in self.race_name:
                            if "环蠡湖" in self.race_name:
                                r_id = "Kn6NygxDqqRrDqPZebWM"
                            elif "江阴时裳新桥" in self.race_name:
                                r_id = "KgZdPzQmJyEL0XNMnoOJ"
                            elif "2025光谷马拉松" in self.race_name:
                                r_id = "Z2X35GO0d5JZmMBoqnQ7"
                            elif "2025南京银行南京马拉松" in self.race_name:
                                r_id = "EA63XdLj8kaRDJqwoMrx"
                            post_data = {"raceid":r_id,"idnum":card_num,"app":"helper","_token":"38Ij7L5jB7GzMtDIoaqIxqdcJDbIC0QGo13qiL5y"}
                        elif "无锡宜兴2025阳羡" in self.race_name:
                            post_data = {"gameid":"GwZ4PJeM0YNYmABV18lL","idnum":card_num,"app":"helper","_token":"38Ij7L5jB7GzMtDIoaqIxqdcJDbIC0QGo13qiL5y"}
                        elif "2025广安马拉松赛" in self.race_name:
                            post_data = {"gameid":"xL1ozbl9DxYWj8Y2BZEn","idnum":card_num,"app":"helper","_token":"leo3VPLpeIRahsObIgxWOzqbnPGz3ixrGSCwKyza"}
                        else:
                            post_data = {"gameid": "Oe3JkEwzDKae04xoN1Kr", "idnum": card_num, "app": "tnf100"}
                        yield Request(url=url, callback=self.parse_ihuipao, dont_filter=True, errback=self.err_parse,
                                      method="POST", body=json.dumps(post_data), headers=header, priority=priority,
                                      meta={"user_id": user_id, "name": name, "serial_number": serial_number})
                elif "#小程序://智赛通" in self.home_url:
                    match_dict = {
                        "2025锦州马拉松": "101151",
                        "2025龙脊梯田百公里跑山赛": "101275",
                        "2025文昌地产榆林马拉松": "101182",
                        "2025宝鸡马拉松": "101208",
                        "2025武夷山马拉松": "101325"
                    }
                    match_id = match_dict.get(self.race_name, "")
                    for user in self.user_list:
                        serial_number = user.get("serialNumber", "")
                        name = user.get("name", "")
                        user_id = user.get("user_id", "")
                        card_num = user.get("card_num", "")
                        priority = int(user.get("priority_level", 0))
                        url = f"https://api.zstong.com.cn/v3/matchChannel/getApplyInfo?matchInfoId={match_id}&cardNo={card_num}"
                        yield Request(url=url, callback=self.parse_zstong, dont_filter=True, errback=self.err_parse, priority=priority,
                                      meta={"user_id": user_id, "name": name, "serial_number": serial_number, "card_num": card_num})
                elif "#小程序://马小助" in self.home_url:
                    match_dict = {
                        "2025建德马拉松": "704165858"
                    }
                    match_id = match_dict.get(self.race_name, "")
                    for user in self.user_list:
                        serial_number = user.get("serialNumber", "")
                        name = user.get("name", "")
                        user_id = user.get("user_id", "")
                        card_num = user.get("card_num", "")
                        priority = int(user.get("priority_level", 0))
                        url = f"https://jiande.zjim.org/p/hzim/match/querybibnumbers.jsf?match={match_id}&fzid=&qr={card_num}"
                        yield Request(url=url, callback=self.parse_maxiaozhu, dont_filter=True, errback=self.err_parse, priority=priority,
                                      meta={"user_id": user_id, "name": name, "serial_number": serial_number, "card_num": card_num})
                elif "#小程序://赛事圈" in self.home_url:
                    header = {
                        "Host": "www.saishiquan.cn",
                        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x63090a13) UnifiedPCWindowsWechat(0xf2541022) XWEB/16467",
                        "Content-Type": "application/json",
                        "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJvcGVuaWQiOiJlODJiZWMwNDM3N2RjY2VjNzc2OWQ1ODgwZDU4NjFlNDRiNTZhOTI5ZDRlODEzYzhlOWNhMDhjMTg4ZGI1ZjIzIiwic2Vzc2lvbl9rZXkiOiJYWitZblZ6MXh6eFhTemZJUFVhMGhRPT0iLCJpYXQiOjE3NTg4NTgyMTIsImV4cCI6MTc1ODk4NzgxMn0.NtdybMTNNZIKIfz084CHGg-IwW5ELu4gRvKgLCXkjZE",
                        "Accept": "*/*"
                    }
                    for user in self.user_list:
                        serial_number = user.get("serialNumber", "")
                        name = user.get("name", "")
                        user_id = user.get("user_id", "")
                        card_num = user.get("card_num", "")
                        priority = int(user.get("priority_level", 0))
                        url = f"https://www.saishiquan.cn/api/pay/getSearchSignUp?keyword={card_num}&themeId=1004"
                        yield Request(url=url, callback=self.parse_saishiquan, dont_filter=True, errback=self.err_parse,
                                      headers=header, priority=priority,
                                      meta={"user_id": user_id, "name": name, "serial_number": serial_number, "card_num": card_num, "header": header})
                elif "#小程序://化元" in self.home_url:
                    match_dict = {
                        "2025合肥大潜山跑山赛": "233",
                        "2025户外特工西宏168·寻秋徽州山径探索": "157",
                    }
                    header = {"Content-Type": "application/json"}
                    url = "https://app.huayuanpt.com/api.php/Match/querySign"
                    for user in self.user_list:
                        serial_number = user.get("serialNumber", "")
                        name = user.get("name", "")
                        user_id = user.get("user_id", "")
                        card_num = user.get("card_num", "")
                        priority = int(user.get("priority_level", 0))
                        data = {"match_id":match_dict.get(self.race_name, ""),"name":name,"card_no":card_num,"card_type":1}
                        yield Request(url=url, callback=self.parse_huayuan, dont_filter=True, errback=self.err_parse, headers=header,
                                      method="POST", body=json.dumps(data), priority=priority,
                                      meta={"user_id": user_id, "name": name, "serial_number": serial_number})
                elif "#小程序://赛路睿时" in self.home_url:
                    match_dict = {
                        "2025“户外特工·山顶见”训练赛—无锡惠山站": 32
                    }
                    header = {
                        "Host": "inrace.songwei.cloud",
                        "Authorization": "Bearer 1",
                        "Content-Type": "application/json"
                    }
                    url = "https://inrace.songwei.cloud/api/mini-program/participant-query/search"
                    for user in self.user_list:
                        serial_number = user.get("serialNumber", "")
                        name = user.get("name", "")
                        user_id = user.get("user_id", "")
                        card_num = user.get("card_num", "")
                        priority = int(user.get("priority_level", 0))
                        data = {"raceId":match_dict.get(self.race_name),"queryConditions":{"name":name,"id_card":card_num}}
                        yield Request(url=url, callback=self.parse_inrace, dont_filter=True, errback=self.err_parse, headers=header,
                                      method="POST", body=json.dumps(data), priority=priority,
                                      meta={"user_id": user_id, "name": name, "serial_number": serial_number})
                elif "#小程序://博捷体育" in self.home_url:
                    match_dict = {
                        "2025玉溪马拉松": "38",
                        "2025眉山东坡马拉松暨跑遍四川（东坡站）": "45"
                    }
                    match_id = match_dict.get(self.race_name, "")
                    url = "https://www.sichuanbojiesports.com/query/runner/post"
                    header = {
                        "Host": "www.sichuanbojiesports.com",
                        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x63090a13) UnifiedPCWindowsWechat(0xf2541022) XWEB/16467",
                        "Content-Type": "application/json",
                        "Accept": "*/*"
                    }
                    for user in self.user_list:
                        serial_number = user.get("serialNumber", "")
                        name = user.get("name", "")
                        user_id = user.get("user_id", "")
                        card_num = user.get("card_num", "")
                        priority = int(user.get("priority_level", 0))
                        post_data = {"id_card": card_num, "race_id": match_id}
                        yield Request(url=url, callback=self.parse_bojie, dont_filter=True, errback=self.err_parse,
                                      method="POST", body=json.dumps(post_data), headers=header, priority=priority,
                                      meta={"user_id": user_id, "name": name, "serial_number": serial_number, "card_num": card_num})
                elif "#小程序://码上开跑" in self.home_url:
                    header = {
                        "Host": "testmatch.umaysports.cn",
                        "X-Tenant": "umay",
                        "xweb_xhr": "1",
                        "Content-Type": "application/json;charset=UTF-8",
                        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x63090a13) UnifiedPCWindowsWechat(0xf2541022) XWEB/16467",
                        "Accept": "*/*"
                    }
                    match_dict = {
                        "2025庐山半程马拉松赛": "1945316244110577664",
                        "2025中国马拉松精英排名赛暨长荡湖马拉松": "1954708486382292992",
                        "2025共青城马拉松": "1980647072508022784"
                    }
                    match_id = match_dict.get(self.race_name, "")
                    if "2025常州西太湖半程马拉松" in self.race_name:
                        match_id = "1955502080697438208"
                    for user in self.user_list:
                        serial_number = user.get("serialNumber", "")
                        name = user.get("name", "")
                        user_id = user.get("user_id", "")
                        card_num = user.get("card_num", "")
                        priority = int(user.get("priority_level", 0))
                        url = f"https://testmatch.umaysports.cn/api/game/apply/entry?page=0&limit=10&id_code_exact={card_num}&game_id={match_id}"
                        yield Request(url=url, callback=self.parse_umaysports, dont_filter=True, errback=self.err_parse,
                                      headers=header, priority=priority,
                                      meta={"user_id": user_id, "name": name, "serial_number": serial_number})
                elif "#小程序://坤悦健康" in self.home_url:
                    match_dict = {
                        "2025锡山宛山湖马拉松": "60"
                    }
                    match_id = match_dict.get(self.race_name, "")
                    for user in self.user_list:
                        serial_number = user.get("serialNumber", "")
                        name = user.get("name", "")
                        user_id = user.get("user_id", "")
                        card_num = user.get("card_num", "")
                        priority = int(user.get("priority_level", 0))
                        header = {
                            "Host": "app.queenrun.cn",
                            "Accept": "application/json, text/plain, */*",
                            "Content-Type": "application/json;charset=utf-8"
                        }
                        url = f"https://app.queenrun.cn/api/v2/race/competition/external/apply/list?userName={name}&certificateNumber={card_num}&externalId={match_id}"
                        yield Request(url=url, callback=self.parse_queenrun, dont_filter=True, errback=self.err_parse,
                                      headers=header, priority=priority,
                                      meta={"user_id": user_id, "name": name, "serial_number": serial_number})
                elif "#小程序://文广体育" in self.home_url:
                    header = {
                        "Host": "xm.xcmsports.com",
                        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x63090a13) UnifiedPCWindowsWechat(0xf2541022) XWEB/16467",
                        "Accept": "application/json",
                        "Content-Type": "application/json;charset=utf-8"
                    }
                    url = "https://xm.xcmsports.com/api/common-service/sendsmsrecord/common/captcha"
                    for user in self.user_list:
                        serial_number = user.get("serialNumber", "")
                        name = user.get("name", "")
                        user_id = user.get("user_id", "")
                        card_num = user.get("card_num", "")
                        priority = int(user.get("priority_level", 0))
                        yield Request(url=url, callback=self.parse_wenguang, dont_filter=True, errback=self.err_parse,
                                      priority=priority,headers=header, meta={"card_num": card_num, "name": name,
                                                                              "serial_number": serial_number, "user_id": user_id})
                elif "合肥马拉松" in self.race_name:
                    header = {
                        "Host": "marathon.hefei.cc",
                        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36",
                        "Accept": "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8",
                        "Referer": "https://marathon.hefei.cc/mlsbaom/query.html"
                    }
                    url = "https://marathon.hefei.cc/mlsbaom/verify.html"
                    for user in self.user_list:
                        serial_number = user.get("serialNumber", "")
                        name = user.get("name", "")
                        user_id = user.get("user_id", "")
                        card_num = user.get("card_num", "")
                        phone = user.get("phone", "")
                        priority = int(user.get("priority_level", 0))
                        yield Request(url=url, callback=self.parse_hefei, dont_filter=True, errback=self.err_parse,
                                      priority=priority,headers=header, meta={"card_num": card_num, "name": name, "phone": phone,
                                                                              "serial_number": serial_number, "user_id": user_id})
                elif "#小程序://京东GO" in self.home_url:
                    match_dict = {
                        "2025北京通州运河半程马拉松": "2831470450000116"
                    }
                    match_id = match_dict.get(self.race_name, "")
                    for user in self.user_list:
                        serial_number = user.get("serialNumber", "")
                        name = user.get("name", "")
                        user_id = user.get("user_id", "")
                        card_num = user.get("card_num", "")
                        priority = int(user.get("priority_level", 0))
                        header = {
                            "Host": "api.m.jd.com",
                            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x63090a13) UnifiedPCWindowsWechat(0xf2541022) XWEB/16467",
                            "Content-Type": "application/x-www-form-urlencoded",
                            "Accept": "*/*",
                            "Referer": "https://servicewechat.com/wx43dc5ea14304fa08/47/page-frame.html"
                        }
                        url = "https://api.m.jd.com/api?functionId=subject_queryParticipantInfo"
                        d_body = {"activityId":match_id,"importType":"participant_info","credentialsNo":card_num}
                        data = {"appid": "laputa-cross-wx", "functionId": "subject_queryParticipantInfo",
                                "body": json.dumps(d_body), "loginType": "2"}
                        yield FormRequest(url=url, callback=self.parse_jdgo, dont_filter=True, errback=self.err_parse,
                                          headers=header, priority=priority, formdata=data,
                                          meta={"user_id": user_id, "name": name, "serial_number": serial_number})
                elif "saihuitong.com" in self.home_url or "cd100k" in self.home_url:
                    domain = urlparse(self.home_url).netloc
                    for user in self.user_list:
                        serial_number = user.get("serialNumber", "")
                        name = user.get("name", "")
                        user_id = user.get("user_id", "")
                        card_num = user.get("card_num", "")
                        priority = int(user.get("priority_level", 0))
                        url = f"http://{domain}/event/applier?name={quote(quote(name))}&&identityCode={card_num}"
                        header = {
                            "Host": domain,
                            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36",
                            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7"""
                        }
                        yield Request(url=url, callback=self.parse_saixun, dont_filter=True, errback=self.err_parse,
                                      headers=header, priority=priority,
                                      meta={"user_id": user_id, "name": name, "serial_number": serial_number})
                elif "sign.runnar.com" in self.home_url:
                    r_id = "".join(re.findall(r"eventId=(.*)", self.home_url)).strip()
                    for user in self.user_list:
                        serial_number = user.get("serialNumber", "")
                        name = user.get("name", "")
                        user_id = user.get("user_id", "")
                        card_num = user.get("card_num", "")
                        priority = int(user.get("priority_level", 0))
                        data = {"matchEventId": r_id, "idType": "1", "idNum": card_num}
                        url = "https://sign.runnar.com/checkin/getRegUserCheckInfoStateByIdNum"
                        header = {
                            "Host": "sign.runnar.com",
                            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36",
                            "Accept": "*/*",
                            "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
                            "X-Requested-With": "XMLHttpRequest"
                        }
                        yield FormRequest(url=url, callback=self.parse_runnar, dont_filter=True, errback=self.err_parse,
                                          headers=header, formdata=data, priority=priority,
                                          meta={"user_id": user_id,
                                                "name": name, "serial_number": serial_number})
                elif "biaodan100.com" in self.home_url:
                    yield Request(url=self.home_url, callback=self.parse_biaodan, dont_filter=True, errback=self.err_parse)
                elif "www.cqnbmarathon.com" in self.home_url:
                    yield Request(url=self.home_url, callback=self.parse_cqcjh, dont_filter=True, errback=self.err_parse)
                elif "u5y67z3d.yichafen.com" in self.home_url:
                    header = {
                        "Host": "u5y67z3d.yichafen.com",
                        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36",
                        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
                        "Referer": "https://u5y67z3d.yichafen.com/qz/1546Xz7mxt",
                        "Cookie": "PHPSESSID=g0b511kl4detl48tnmujtpf3b6"
                    }
                    yield Request(url=self.home_url, callback=self.parse_yichafen, dont_filter=True, errback=self.err_parse, headers=header, meta={"header": header})
                elif "数字心动" in self.home_url:
                    client = pyssdb.Client(host=self.ssdb_host, port=self.ssdb_port)
                    try:
                        token = client.qfront("shuzixindong_cookie")
                    except:
                        token = ""
                    finally:
                        client.disconnect()
                    if token:
                        header = {
                            "machineCode": "6bd839d8b9f7f76d",
                            "osId": "1002",
                            "device": "pad/12 HUAWEI MGA-AL00",
                            "versionNumber": "519",
                            "versionCode": "5.54.0",
                            "terminalType": "1",
                            "Content-Type": "application/json; charset=UTF-8",
                            "Host": "api-changzheng.chinaath.com",
                            "token": token.decode('utf-8')
                        }
                        for user in self.user_list:
                            serial_number = user.get("serialNumber", "")
                            name = user.get("name", "")
                            user_id = user.get("user_id", "")
                            card_num = user.get("card_num", "")
                            priority = int(user.get("priority_level", 0))
                            img_url = "https://api-changzheng.chinaath.com/changzheng-basic-center-api/api/imageVerify/getUniqueIdByBusinessType?imageVerifyBusinessType=5"
                            yield Request(url=img_url, callback=self.parse_shuzixindong, headers=header, dont_filter=True,
                                          priority=priority, meta={"header": header, "serial_number": serial_number, "name": name,
                                                                   "user_id": user_id, "card_num": card_num})
                    else:
                        self.logger.info("数字心动未登陆")
                        self.upload_procedure({"race_id": self.race_id, "code": 203, "message": "数字心动未登陆，请先进行登陆"})
                        self.close_after_idle = True
                        self.force_to_close_spider = True
                elif "第一赛道" in self.home_url:
                    url = "https://matchapi.gusto.cn/api/user/card/create"
                    header = {
                        "Host": "matchapi.gusto.cn",
                        "client-token": "15ae104746b40c2e74e9e31cf3529f38",
                        # "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x63090a13) UnifiedPCWindowsWechat(0xf2541022) XWEB/16467",
                        "Content-Type": "application/json;charset=UTF-8"
                    }

                    user = self.user_list.pop(0)
                    serial_number = user.get("serialNumber", "")
                    name = user.get("name", "")
                    user_id = user.get("user_id", "")
                    card_num = user.get("card_num", "")
                    priority = int(user.get("priority_level", 0))
                    if int(card_num[-2:-1]) % 2 == 0:
                        sex = 2
                    else:
                        sex = 1
                    data = {"me":False,"realName":name,"pinyin":"ZHANG SAN","sex":sex,"cardType":1,"cardNumber":card_num,"birthday":846633600000,"country":"中国","province":"北京市","city":"北京市","area":"东城区","address":"东大街234号","mobile":"18721453548","email":"dasda@163.com","size":"L","emergencyContact":"李四","emergencyContactMobile":"18912357461","bloodType":1}

                    yield Request(url=url, method="POST", callback=self.parse_diyisaidao, body=json.dumps(data), priority=priority,
                                  headers=header, dont_filter=True, errback=self.err_parse,
                                  meta={"header": header, "serial_number": serial_number, "user_id": user_id,
                                        "name": name})
                elif "马拉马拉" in self.home_url:
                    header = {
                        "Host": "user-gw.mararun.com",
                        "Accept": "application/json, text/plain, */*"
                    }
                    url = "https://user-gw.mararun.com/v1/captcha/code"
                    for user in self.user_list:
                        serial_number = user.get("serialNumber", "")
                        name = user.get("name", "")
                        user_id = user.get("user_id", "")
                        card_num = user.get("card_num", "")
                        priority = int(user.get("priority_level", 0))
                        yield Request(url=url, callback=self.parse_malamala, headers=header, priority=priority,
                                      dont_filter=True, errback=self.err_parse, meta={"header": header, "serial_number": serial_number,
                                                                                      "name": name, "user_id": user_id,
                                                                                      "card_num": card_num})
                elif "sports.beedancing-timing.com.cn" in self.home_url:
                    r_id = "".join(re.findall(r"id=(.*)", self.home_url)).strip()
                    for user in self.user_list:
                        serial_number = user.get("serialNumber", "")
                        name = user.get("name", "")
                        user_id = user.get("user_id", "")
                        card_num = user.get("card_num", "")
                        priority = int(user.get("priority_level", 0))
                        data = {"race_id": int(r_id), "cno": "", "idcard": card_num}
                        url = "https://sports.beedancing-timing.com.cn/api/people/getbyidcard"
                        header = {
                            "Host": "sports.beedancing-timing.com.cn",
                            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36",
                            "content-type": "application/json",
                            "Accept": "*/*"
                        }
                        yield Request(url=url, callback=self.parse_beedancing, dont_filter=True, errback=self.err_parse,
                                      method="POST", body=json.dumps(data), headers=header, priority=priority,
                                      meta={"user_id": user_id, "name": name, "serial_number": serial_number})
                elif "www.aituye.com.cn" in self.home_url:
                    for user in self.user_list:
                        serial_number = user.get("serialNumber", "")
                        name = user.get("name", "")
                        user_id = user.get("user_id", "")
                        card_num = user.get("card_num", "")
                        priority = int(user.get("priority_level", 0))
                        url = f"http://www.aituye.com.cn/bmcx1?title={card_num}"
                        yield Request(url=url, callback=self.parse_aituye, dont_filter=True, errback=self.err_parse,
                                      priority=priority,
                                      meta={"user_id": user_id, "name": name, "serial_number": serial_number})
                elif "h5.jifengsports.com" in self.home_url:
                    for user in self.user_list:
                        serial_number = user.get("serialNumber", "")
                        name = user.get("name", "")
                        user_id = user.get("user_id", "")
                        card_num = user.get("card_num", "")
                        priority = int(user.get("priority_level", 0))
                        url = "https://h5.jifengsports.com/v2/query/signUp"
                        header = {
                            "Host": "h5.jifengsports.com",
                            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 NetType/WIFI MicroMessenger/7.0.20.1781(0x6700143B) WindowsWechat(0x63090a13) UnifiedPCWindowsWechat(0xf2541022) XWEB/16467 Flue",
                            "content-type": "application/x-www-form-urlencoded",
                            "Accept": "application/json, text/plain, */*",
                            "Authorization": "2591cf0c8fa1ebffcd7bf809d5d6aee6"
                        }
                        data = {"id": "240", "type": "1", "idcarno": card_num}
                        yield FormRequest(url=url, callback=self.parse_jifeng, dont_filter=True, errback=self.err_parse,
                                          priority=priority, headers=header, formdata=data,
                                          meta={"user_id": user_id, "name": name, "serial_number": serial_number})
                elif self.home_url.endswith("querybibnumbers.jsf"):
                    yield Request(url=self.home_url, callback=self.parse_baidian, dont_filter=True, errback=self.err_parse)
                elif "running8.com" in self.home_url:
                    yield Request(url=self.home_url, callback=self.parse_running, dont_filter=True, errback=self.err_parse)
                elif "wx.iborun.cn" in self.home_url:
                    header = {
                        "Host": "wx.iborun.cn",
                        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36",
                        "Accept": "application/json, text/plain, */*"
                    }
                    for user in self.user_list:
                        serial_number = user.get("serialNumber", "")
                        name = user.get("name", "")
                        user_id = user.get("user_id", "")
                        card_num = user.get("card_num", "")
                        priority = int(user.get("priority_level", 0))
                        url = f"https://wx.iborun.cn/mobile-api/signup/getSignUpList?truename={name}&idCode={card_num}&pageNum=1&pageSize=20"

                        yield Request(url=url, callback=self.parse_iborun, dont_filter=True, errback=self.err_parse,
                                      headers=header, priority=priority,
                                      meta={"user_id": user_id, "name": name, "serial_number": serial_number})
                elif "www.guanghan-marathon.com" in self.home_url or "www.sxym.org.c" in self.home_url:
                    if "www.sxym.org.c" in self.home_url:
                        host = "www.sxym.org.cn"
                        url = "http://www.sxym.org.cn/b/qUVRVb/query.html?isbxapimode=true"
                    else:
                        host = "www.guanghan-marathon.com"
                        url = "http://www.guanghan-marathon.com/b/FbuAN3/query.html?isbxapimode=true"
                    header = {
                        "Host": host,
                        "Accept": "text/plain, */*; q=0.01",
                        "X-Requested-With": "XMLHttpRequest",
                        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36",
                        "Content-Type": "text/plain"
                    }
                    for user in self.user_list:
                        serial_number = user.get("serialNumber", "")
                        name = user.get("name", "")
                        user_id = user.get("user_id", "")
                        card_num = user.get("card_num", "")
                        priority = int(user.get("priority_level", 0))
                        post_data = f"""<?xml version="1.0" encoding="utf-8"?><BxMessage><AppId>BxAPI</AppId><Type>1</Type><Action>pageapi_query</Action><Data><action>query</action><idcardnumber>{card_num}</idcardnumber></Data></BxMessage>"""
                        yield Request(url=url, callback=self.parse_guanghan, dont_filter=True, errback=self.err_parse,
                                      method='POST', body=post_data, headers=header, priority=priority,
                                      meta={"user_id": user_id, "name": name, "serial_number": serial_number})
                elif "rs-score.xtibo.com" in self.home_url:
                    num = "".join(re.findall(r"certificate/(\d+)", self.home_url)).strip()
                    if num:
                        url = f"https://rs-score.xtibo.com/cert/race/detail/{num}/"
                    else:
                        num = "".join(re.findall(r"runnerapp/(.+)", self.home_url)).strip()
                        url = f"https://rs-score.xtibo.com/system/runnerinfo/runnerapp/detail/{num}/"
                    for user in self.user_list:
                        serial_number = user.get("serialNumber", "")
                        name = user.get("name", "")
                        user_id = user.get("user_id", "")
                        card_num = user.get("card_num", "")
                        priority = int(user.get("priority_level", 0))
                        url = f"{url}{card_num}"
                        yield Request(url=url, callback=self.parse_xtibo, dont_filter=True, errback=self.err_parse, priority=priority,
                                      meta={"user_id": user_id, "name": name, "serial_number": serial_number})
                elif "swordfish.com" in self.home_url:
                    header = {
                        "Host": "39.105.11.100:6031",
                        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36",
                        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
                        "Accept-Encoding": "gzip, deflate",
                        "Accept-Language": "zh,zh-CN;q=0.9"
                    }
                    num = "".join(re.findall(r"/(\d+)", self.home_url)).strip()
                    url = f"http://39.105.11.100:6031/api/OffRoad/GetCertInfo/{num}"
                    yield Request(url=url, callback=self.parse_swordfish, dont_filter=True, errback=self.err_parse,
                                  headers=header)
                elif "wxxjty.wbs.fit" in self.home_url:
                    s_no = "".join(re.findall(r"sNo=(.*)", self.home_url)).strip()
                    url = "https://wxxjty.wbs.fit/index/index/checkCertExists"
                    if "2025长宁蜀南竹海半程马拉松" in self.race_name:
                        url = "https://wxxjty.wbs.fit/index/index/checkPlayerExists"
                    if "2025“金钻习酒”美丽中国·全民健身跑（海南·海口站）" in self.race_name:
                        url = "https://wxxjty.wbs.fit/index/index/checkMZSfzExists"
                    for user in self.user_list:
                        serial_number = user.get("serialNumber", "")
                        name = user.get("name", "")
                        user_id = user.get("user_id", "")
                        card_num = user.get("card_num", "")
                        priority = int(user.get("priority_level", 0))
                        data = {"sNo": s_no, "haoma": card_num, "sfz": "", "xm": ""}
                        if "2025“金钻习酒”美丽中国·全民健身跑（海南·海口站）" in self.race_name:
                            data = {"sNo": s_no, "sfz": card_num}
                        yield FormRequest(url=url, callback=self.parse_wbs, dont_filter=True, priority=priority,
                                          errback=self.err_parse, formdata=data, headers={"X-Requested-With": "XMLHttpRequest"},
                                          meta={"user_id": user_id, "s_no": s_no,
                                                "name": name, "serial_number": serial_number, "card_num": card_num})
                elif "spoorts.cn" in self.home_url:
                    num = "".join(re.findall(r"race_id=(\d+)", self.home_url)).strip()
                    if "register.spoorts.cn" in self.home_url:
                        host = "sapi.spoorts.cn"
                        header = {
                            "X-Spoorts-Client": "spoorts_api_v2",
                            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36",
                            "Accept": "application/json, text/plain, */*",
                            "X-Seed": "1442",
                            "X-Requested-With": "XMLHttpRequest",
                            "X-Sign": "rNzALIuSZqJrbPCIfvDJ17YxB9A="
                        }
                    elif "testreg.spoorts.cn" in self.home_url:
                        host = "openapi.spoorts.cn"
                        header = {
                            "X-Spoorts-Client": "spoorts_api_v2",
                            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36",
                            "Accept": "application/json, text/plain, */*",
                            "X-Seed": "1340",
                            "X-Requested-With": "XMLHttpRequest",
                            "X-Sign": "3efGjcIeoRb44Z3t/qFtD6Z9vG8="
                        }
                    if host:
                        for user in self.user_list:
                            serial_number = user.get("serialNumber", "")
                            name = user.get("name", "")
                            user_id = user.get("user_id", "")
                            card_num = user.get("card_num", "")
                            priority = int(user.get("priority_level", 0))
                            url = f"https://{host}/api/v1/enrolls/query_result_enroll_info.json?race_id={num}&real_name={name}&id_card={card_num}"
                            yield Request(url=url, callback=self.parse_spoorts, dont_filter=True, errback=self.err_parse,
                                          headers=header, priority=priority,
                                          meta={"serial_number": serial_number, "user_id": user_id, "name": name, "handle_httpstatus_list": [500]})
                elif "irunner.mobi" in self.home_url:
                    token = "d30c6ce813185cffb82e98ab51639ed6"
                    match_eng = "".join(re.findall(r"match_eng=(.*?)[#&]", self.home_url)).strip()
                    url = f"https://mix-api.irunner.mobi/match/apply-search?match_eng={match_eng}&app_type=&access_token="
                    for user in self.user_list:
                        serial_number = user.get("serialNumber", "")
                        name = user.get("name", "")
                        user_id = user.get("user_id", "")
                        card_num = user.get("card_num", "")
                        priority = int(user.get("priority_level", 0))
                        body = (
                            "------WebKitFormBoundaryw5lBv8ld8DimAAxW\r\n"
                            'Content-Disposition: form-data; name="id_number"\r\n\r\n'
                            f"{card_num}\r\n"
                            f"------WebKitFormBoundaryw5lBv8ld8DimAAxW\r\n"
                            'Content-Disposition: form-data; name="access_token"\r\n\r\n'
                            f"{token}\r\n"
                            "------WebKitFormBoundaryw5lBv8ld8DimAAxW--\r\n"
                        ).encode("utf-8")
                        yield Request(url=url, callback=self.parse_irunner, dont_filter=True, errback=self.err_parse, body=body,
                                      method="POST", headers=self.headers, priority=priority,
                                      meta={"user_id": user_id, "token": token,
                                            "name": name, "serial_number": serial_number, "match_eng": match_eng})
                else:
                    base64_str = self.home_url.split("certificateQuery?")[1]
                    decoded_bytes = base64.b64decode(base64_str)
                    decoded_string = decoded_bytes.decode('utf-8')
                    cmpt_id = "".join(re.findall(r"cmptId=(.*)&", decoded_string))
                    for user in self.user_list:
                        serial_number = user.get("serialNumber", "")
                        name = user.get("name", "")
                        user_id = user.get("user_id", "")
                        card_num = user.get("card_num", "")
                        priority = int(user.get("priority_level", 0))
                        url = f"https://timerbackend.geexek.com/getCertificatesURL.do?cmptId={cmpt_id}&keyword={card_num}"
                        yield Request(url=url, callback=self.parse_result, dont_filter=True,
                                      errback=self.err_parse, priority=priority,
                                      meta={"cmpt_id": cmpt_id, "card_num": card_num, "serial_number": serial_number,
                                            "name": name, "user_id": user_id})

    def parse_result(self, response):
        user_id = response.meta.get("user_id", "")
        cmpt_id = response.meta.get("cmpt_id", "")
        card_num = response.meta.get("card_num", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        self.logger.info(f"开始获取{card_num}在比赛{cmpt_id}的号码牌信息")
        try:
            pic_name = f'{calc_str_md5(f"{cmpt_id}_{card_num}")}.jpg'
            dir_path = os.path.join(file_path, self.name_first)
            if not os.path.exists(dir_path):
                os.makedirs(dir_path)
            save_path = os.path.join(dir_path, pic_name)
            if not os.path.exists(save_path):
                with open(save_path, "wb") as f:
                    f.write(response.body)
                upload_path = f"flow/{self.race_id}/{user_id}/raceno/{pic_name}"
                upload_flag = upload_file(save_path, upload_path)
                if upload_flag:
                    self.logger.info(f"{save_path}上传成功：{upload_path}")
                else:
                    self.logger.info(f"{save_path}上传失败：{upload_path}")
                result_data = {"race_id": cmpt_id, "name": name, "user_id": user_id, "race_no": "", "runner_status": "",
                               "race_name": self.race_name, "enroll_status": "", "race_no_pic": upload_path}
                result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data, user_id=user_id)
                yield result
        except Exception:
            self.logger.info(f"获取{card_num}在比赛{cmpt_id}的号码牌信息时出错：{traceback.format_exc()}")

    def parse_haituo(self, response):
        try:
            self.logger.info("开始获取报名信息")
            self.return_flag = False
            link = response.xpath("//form[@id='qForm']/@action").extract_first()
            qRaceId = response.xpath("//input[@id='qRaceId']/@value").extract_first()
            qID = response.xpath("//input[@id='qID']/@value").extract_first()
            url = response.urljoin(link.strip())
            for user in self.user_list:
                serial_number = user.get("serialNumber", "")
                name = user.get("name", "")
                user_id = user.get("user_id", "")
                card_num = user.get("card_num", "")
                priority = int(user.get("priority_level", 0))
                data = {"qRaceId": qRaceId, "qID": qID, "athleteName": name, "idNumber": card_num}
                yield FormRequest(url, callback=self.parse_haituo_detail, formdata=data, dont_filter=True,
                                  errback=self.err_parse, headers=self.ht_header, priority=priority,
                                  meta={"user_id": user_id, "card_num": card_num,
                                        "serial_number": serial_number, "name": name})
        except Exception:
            self.logger.info(f"获取报名信息错误：{traceback.format_exc()}")

    def parse_haituo_detail(self, response):
        user_id = response.meta.get("user_id", "")
        card_num = response.meta.get("card_num", "")
        name = response.meta.get("name", "")
        serial_number = response.meta.get("serial_number", "")
        try:
            self.logger.info(f"开始获取{name}的报名信息")
            cmpt_id = "".join(re.findall(r"[?&]raceId=(\d+)", response.url))
            if cmpt_id:
                title_list = response.xpath("//div[@class='mui-pull-left']//text()").extract()
                title_list = [t.strip() for t in title_list]
                value_list = response.xpath("//div[@class='mui-pull-right']//text()").extract()
                value_list = [v.strip() for v in value_list]
                data_dict = dict(zip(title_list, value_list))
                bib_no = data_dict.get("BIB", "")
                event_name = data_dict.get("EVENT NAME", "") or data_dict.get("参赛项目", "")
                img_base64 = response.xpath("//img[@id='certifImg']/@src").extract_first()
                if img_base64:
                    image_data = base64.b64decode(img_base64.split(",", 1)[1])
                    pic_name = f'{calc_str_md5(f"{cmpt_id}_{card_num}")}.jpg'
                    dir_path = os.path.join(file_path, self.name_first)
                    if not os.path.exists(dir_path):
                        os.makedirs(dir_path)
                    save_path = os.path.join(dir_path, pic_name)
                    if not os.path.exists(save_path):
                        with open(save_path, "wb") as f:
                            f.write(image_data)
                        upload_path = f"flow/{self.race_id}/{user_id}/raceno/{pic_name}"
                        upload_flag = upload_file(save_path, upload_path)
                        if upload_flag:
                            self.logger.info(f"{save_path}上传成功：{upload_path}")
                        else:
                            self.logger.info(f"{save_path}上传失败：{upload_path}")
                        result_data = {"race_id": cmpt_id, "name": name, "user_id": user_id, "race_no": bib_no, "runner_status": "",
                                       "race_name": self.race_name, "enroll_status": "", "item_name": event_name, "race_no_pic": upload_path}
                        result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data,
                                                user_id=user_id)
                        yield result
                else:
                    result_data = {"race_id": cmpt_id, "name": name, "user_id": user_id, "race_no": bib_no, "runner_status": "",
                                   "race_name": self.race_name, "enroll_status": "", "item_name": event_name, "race_no_pic": ""}
                    athelet_id = "".join(re.findall(r"atheletID.value = '(.*?)';", response.text)).strip()
                    event_id = "".join(re.findall(r"eventId.value = '(.*?)';", response.text)).strip()
                    dbt_id = "".join(re.findall(r"dbt.value = '(.*?)';", response.text)).strip()
                    if all([athelet_id, event_id, dbt_id]):
                        boundary = "WebKitFormBoundaryw5lBv8ld8DimAAxW"
                        body = f"""------{boundary}\r
Content-Disposition: form-data; name="memberId"\r
\r
{bib_no}\r
------{boundary}\r
Content-Disposition: form-data; name="raceId"\r
\r
{cmpt_id}\r
------{boundary}\r
Content-Disposition: form-data; name="eventId"\r
\r
{event_id}\r
------{boundary}\r
Content-Disposition: form-data; name="atheletId"\r
\r
{athelet_id}\r
------{boundary}\r
Content-Disposition: form-data; name="dbt"\r
\r
{dbt_id}\r
------{boundary}\r
Content-Disposition: form-data; name="photoData"\r
\r
\r
------{boundary}--"""
                        url = "https://rqs.racetigertiming.com/Result/Certificate"
                        yield Request(url=url, callback=self.parse_haituo_cert, dont_filter=True, errback=self.err_parse,
                                      body=body, method="POST", headers=self.headers,
                                      meta={"user_id": user_id, "result_data": result_data, "card_num": card_num,
                                            "name": name, "serial_number": serial_number, "cmpt_id": cmpt_id})
                    else:
                        result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data, user_id=user_id)
                        yield result
            else:
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                yield result
        except Exception:
            self.logger.info(f"获取{name}的报名信息错误：{traceback.format_exc()}")

    def parse_haituo_cert(self, response):
        user_id = response.meta.get("user_id", "")
        result_data = response.meta.get("result_data", {})
        name = response.meta.get("name", "")
        card_num = response.meta.get("card_num", "")
        cmpt_id = response.meta.get("cmpt_id", "")
        serial_number = response.meta.get("serial_number", "")
        try:
            self.logger.info(f"开始获取{name}的号码簿")
            img_base64 = response.xpath("//img[@id='certifImg']/@src").extract_first()
            if img_base64:
                image_data = base64.b64decode(img_base64.split(",", 1)[1])
                pic_name = f'{calc_str_md5(f"{cmpt_id}_{card_num}")}.jpg'
                dir_path = os.path.join(file_path, self.name_first)
                if not os.path.exists(dir_path):
                    os.makedirs(dir_path)
                save_path = os.path.join(dir_path, pic_name)
                if not os.path.exists(save_path):
                    with open(save_path, "wb") as f:
                        f.write(image_data)
                    upload_path = f"flow/{self.race_id}/{user_id}/raceno/{pic_name}"
                    upload_flag = upload_file(save_path, upload_path)
                    if upload_flag:
                        self.logger.info(f"{save_path}上传成功：{upload_path}")
                    else:
                        self.logger.info(f"{save_path}上传失败：{upload_path}")
                    result_data["race_no_pic"] = upload_path
                    result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data, user_id=user_id)
                    yield result
            else:
                result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data, user_id=user_id)
                yield result
        except Exception:
            self.logger.info(f"获取{name}的号码簿错误：{traceback.format_exc()}")

    def parse_51race(self, response):
        serial_number = response.meta.get("serial_number", "")
        user_id = response.meta.get("user_id", "")
        card_num = response.meta.get("card_num", "")
        name = response.meta.get("name", "")
        try:
            self.logger.info(f"开始获取{name}的报名信息")
            data_list = json.loads(response.text).get("data", [])
            if data_list:
                for data in data_list:
                    group_name = data.get("groupName", "")
                    number_card = data.get("number_card", "")
                    runner_status = "报名成功" if number_card else ""
                    result_data = {"race_id": self.race_id, "name": name, "user_id": user_id, "race_no": number_card, "runner_status": runner_status,
                                   "race_name": data.get("raceName", ""), "enroll_status": "", "item_name": group_name}
                    portal_id = data.get("portal_id", "")
                    enroll_status = data.get("statusshenghe_text", "")
                    if portal_id and enroll_status  == "审核通过":
                        img_url = f"http://51race.com/mm/{portal_id}/shownumber?identity_id={card_num}"
                        yield Request(img_url, callback=self.parse_pic, errback=self.err_parse, dont_filter=True,
                                      meta={"user_id": user_id, "card_num": card_num, "serial_number": serial_number,
                                            "name": name, "result_data": result_data})
                    else:
                        result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data, user_id=user_id)
                        yield result
            else:
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                yield result
        except Exception:
            self.logger.info(f"获取{name}的报名信息错误：{traceback.format_exc()}")

    def parse_pic(self, response):
        user_id = response.meta.get("user_id", "")
        card_num = response.meta.get("card_num", "")
        name = response.meta.get("name", "")
        serial_number = response.meta.get("serial_number", "")
        _result_data = {"race_id": self.race_id, "name": name, "user_id": user_id, "race_no": "", "runner_status": "",
                        "race_name": self.race_name, "enroll_status": "", "item_name": ""}
        result_data = response.meta.get("result_data", _result_data)
        self.logger.info(f"开始获取{card_num}号码牌信息")
        try:
            pic_flag = True
            if "凯乐石" in self.race_name:
                content_type = response.headers.get('Content-Type', '').lower().decode()
                if "image" in content_type or "img" in content_type:
                    pass
                else:
                    pic_flag = False
                    result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                    yield result
            if pic_flag:
                content_type = response.headers.get('Content-Type', '').lower().decode()
                if "image" in content_type or "img" in content_type:
                    race_no = result_data.get("race_no", "")
                    pic_name = f'{calc_str_md5(f"{card_num}_{race_no}{self.race_id}")}.jpg'
                    dir_path = os.path.join(file_path, self.name_first)
                    if not os.path.exists(dir_path):
                        os.makedirs(dir_path)
                    save_path = os.path.join(dir_path, pic_name)
                    if not os.path.exists(save_path):
                        with open(save_path, "wb") as f:
                            f.write(response.body)
                        upload_path = f"flow/{self.race_id}/{user_id}/raceno/{pic_name}"
                        upload_flag = upload_file(save_path, upload_path)
                        if upload_flag:
                            self.logger.info(f"{save_path}上传成功：{upload_path}")
                        else:
                            self.logger.info(f"{save_path}上传失败：{upload_path}")
                        result_data["race_no_pic"] = upload_path
                result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data, user_id=user_id)
                yield result
        except Exception:
            self.logger.info(f"获取{card_num}的号码牌信息时出错：{traceback.format_exc()}")

    def parse_marathon(self, response):
        user_id = response.meta.get("user_id", "")
        card_num = response.meta.get("card_num", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        try:
            self.logger.info(f"开始获取token")
            token = response.xpath("//meta[@name='csrf-token']/@content").extract_first()
            url = "https://www.marathonchangsha.com/signup-search"
            post_data = {"_token": token, "idcard": card_num, "realname": name, "merchant": "csmls"}
            yield FormRequest(url=url, callback=self.parse_marathon_no, dont_filter=True,
                              errback=self.err_parse, formdata=post_data,
                              meta={"user_id": user_id, "name": name, "serial_number": serial_number})
        except Exception:
            self.logger.info(f"获取token错误：{traceback.format_exc()}")

    def parse_marathon_no(self, response):
        user_id = response.meta.get("user_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        try:
            self.logger.info(f"开始获取{name}的参赛号")
            data = json.loads(response.text).get("data", {})
            if data:
                no = data.get("haoma_bid", {}).get("hmb", "")
                group = data.get("infos", {}).get("projectname", "")
                user_name = data.get("users", {}).get("name", "")
                sign_status = data.get("reg_status", {}).get("status_text", "")
                result_data = {"race_id": self.race_id, "name": user_name or name, "user_id": user_id,
                               "race_no": no,
                               "runner_status": "", "race_name": self.race_name,
                               "enroll_status": sign_status,
                               "item_name": group, "sign_status": sign_status,
                               "race_no_pic": ""}
                result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data,
                                        user_id=user_id)
                yield result
            else:
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                yield result
        except Exception:
            self.logger.info(f"获取{name}的参赛号错误：{traceback.format_exc()}")

    def parse_hrb(self, response):
        user_id = response.meta.get("user_id", "")
        card_num = response.meta.get("card_num", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        domain = response.meta.get("domain", "")
        try:
            self.logger.info(f"开始获取race_id")
            r_id = json.loads(response.text).get("data", {}).get("raceId", "")
            url = "https://api-changzheng.chinaath.com/changzheng-basic-center-api/api/imageVerify/getUniqueIdByBusinessType?imageVerifyBusinessType=2"
            yield Request(url=url, callback=self.parse_hrb_id, dont_filter=True, errback=self.err_parse,
                          meta={"user_id": user_id, "card_num": card_num, "name": name,
                                "serial_number": serial_number, "domain": domain, "r_id": r_id})
        except Exception:
            self.logger.info(f"获取race_id错误：{traceback.format_exc()}")

    def parse_hrb_id(self, response):
        user_id = response.meta.get("user_id", "")
        card_num = response.meta.get("card_num", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        domain = response.meta.get("domain", "")
        r_id = response.meta.get("r_id", "")
        try:
            self.logger.info(f"开始获取img_id")
            img_id = json.loads(response.text).get("data", "")
            img_url = f"https://api-changzheng.chinaath.com/changzheng-basic-center-api/api/imageVerify/getVerifyCode?uniqueId={img_id}"
            yield Request(img_url, callback=self.parse_hrb_img, errback=self.err_parse, dont_filter=True,
                          meta={"user_id": user_id, "card_num": card_num, "r_id": r_id,
                                "serial_number": serial_number, "name": name, "img_id": img_id, "domain": domain})
        except Exception:
            self.logger.info(f"获取img_id错误：{traceback.format_exc()}")

    def parse_hrb_img(self, response):
        user_id = response.meta.get("user_id", "")
        card_num = response.meta.get("card_num", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        img_id = response.meta.get("img_id", "")
        domain = response.meta.get("domain", "")
        r_id = response.meta.get("r_id", "")
        try:
            self.logger.info(f"开始打码")
            ocr = ddddocr.DdddOcr(beta=True)
            yzm = ocr.classification(response.body)
            post_data = {"cardNumber": card_num, "domainName": domain, "imageUniqueId": img_id,
                         "imageVerifyCode": yzm, "raceId": r_id}
            url = "https://api-changzheng.chinaath.com/changzheng-website-center-api/api/official/website/getUserRegistrationBaseInfo"
            header = {
                "Host": "api-changzheng.chinaath.com",
                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36",
                "Content-Type": "application/json",
                "Accept": "application/json, text/plain, */*",
                "Accept-Encoding": "gzip, deflate, br"
            }
            yield Request(url, callback=self.parse_hrb_raceno, errback=self.err_parse, method="POST",
                          body=json.dumps(post_data), headers=header, dont_filter=True,
                          meta={"user_id": user_id, "card_num": card_num, "r_id": r_id,
                                "serial_number": serial_number, "name": name, "domain": domain})
        except Exception:
            self.logger.info(f"打码错误：{traceback.format_exc()}")

    def parse_hrb_raceno(self, response):
        user_id = response.meta.get("user_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        card_num = response.meta.get("card_num", "")
        domain = response.meta.get("domain", "")
        r_id = response.meta.get("r_id", "")
        try:
            self.logger.info(f"开始获取{name}参赛号")
            msg = json.loads(response.text).get("msg")
            if msg == "SUCCESS":
                content = json.loads(response.text).get("data", {})
                race_no = content.get("entryNumber", "")
                draw_status = content.get("drawStatus", 0)
                status_dict = {0: "无需抽签", 1: "待抽签", 2: "未中签", 3: "已中签", 4: "未中签", 101: "候补中", 102: "未审核通过"}
                sign_status = status_dict.get(draw_status, "-")
                result_data = {"race_id": self.race_id or content.get("raceId", ""), "name": name, "user_id": user_id, "race_no": race_no,
                               "runner_status": "", "race_name":  content.get("raceName", "") or self.race_name, "enroll_status": sign_status,
                               "item_name": content.get("itemName", ""), "sign_status": sign_status,
                               "race_no_pic": ""}
                result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data, user_id=user_id)
                yield result
            elif "验证码" in msg:
                if self.retry_time > 0:
                    self.retry_time -= 1
                    url = "https://api-changzheng.chinaath.com/changzheng-basic-center-api/api/imageVerify/getUniqueIdByBusinessType?imageVerifyBusinessType=2"
                    yield Request(url=url, callback=self.parse_hrb_id, dont_filter=True, errback=self.err_parse,
                                  meta={"user_id": user_id, "card_num": card_num,
                                        "name": name, "serial_number": serial_number, "domain": domain, "r_id": r_id})
                else:
                    result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                    yield result
            else:
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                yield result

        except Exception:
            self.logger.info(f"获取{name}参赛号错误：{traceback.format_exc()}")

    def parse_shenyang(self, response):
        user_id = response.meta.get("user_id", "")
        card_num = response.meta.get("card_num", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        try:
            self.logger.info(f"开始获取沈阳马拉松的sessionid和验证码链接")
            img_url = json.loads(response.text).get("image", "")
            session_id = json.loads(response.text).get("sessionID", "")
            yield Request(img_url, callback=self.parse_shenyang_img, errback=self.err_parse, dont_filter=True,
                          meta={"user_id": user_id, "card_num": card_num,
                                "serial_number": serial_number, "name": name, "session_id": session_id})
        except Exception:
            self.logger.info(f"获取沈阳马拉松的sessionid和验证码链接错误：{traceback.format_exc()}")

    def parse_shenyang_img(self, response):
        user_id = response.meta.get("user_id", "")
        card_num = response.meta.get("card_num", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        session_id = response.meta.get("session_id", "")
        try:
            self.logger.info(f"开始打码")
            ocr = ddddocr.DdddOcr(beta=True)
            yzm = ocr.classification(response.body)
            if "2025沈阳马拉松" in self.race_name:
                match_id = "8379122095068653"
            elif "2025天津马拉松" in self.race_name:
                match_id = "8377244456303104"
            elif "2025蒙牛成都马拉松" in self.race_name:
                match_id = "8264176489334086"
            elif "2025遂宁观音湖马拉松" in self.race_name:
                match_id = "8454673774509280"
            url = f"https://saas-user-gw.mararun.com/v1/application/search?matchID={match_id}&identityCard={card_num}&sessionID={session_id}&code={yzm}"
            header = {
                "Host": "saas-user-gw.mararun.com",
                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36",
                "Content-Type": "application/json",
                "Accept": "application/json, text/plain, */*"
            }
            yield Request(url, callback=self.parse_shenyang_raceno, errback=self.err_parse,
                          headers=header, dont_filter=True,
                          meta={"user_id": user_id, "card_num": card_num,
                                "serial_number": serial_number, "name": name, "handle_httpstatus_list": [404]})
        except Exception:
            self.logger.info(f"打码错误：{traceback.format_exc()}")

    def parse_shenyang_raceno(self, response):
        user_id = response.meta.get("user_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        card_num = response.meta.get("card_num", "")
        try:
            self.logger.info(f"开始获取{name}参赛号")
            content = json.loads(response.text)
            msg = content.get("error", {}).get("message", "")
            if "验证码" in msg:
                if self.retry_time > 0:
                    self.retry_time -= 1
                    url = "https://saas-user-gw.mararun.com/v1/captcha/code"
                    yield Request(url=url, callback=self.parse_shenyang, dont_filter=True, errback=self.err_parse,
                                  headers={"Accept": "application/json, text/plain, */*"},
                                  meta={"user_id": user_id, "card_num": card_num,
                                        "name": name, "serial_number": serial_number, "retry_flag": True})
                else:
                    result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                    yield result
            elif "报名不存在" in msg:
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                yield result
            else:
                race_no = content.get("CNO", "")
                sign_status = content.get("showProcessName", "").replace("恭喜您，", "")
                result_data = {"race_id": self.race_id or content.get("raceId", ""), "name": name, "user_id": user_id, "race_no": race_no,
                               "runner_status": "", "race_name": self.race_name, "enroll_status": sign_status,
                               "item_name": content.get("matchEventName", ""), "sign_status": sign_status,
                               "race_no_pic": ""}
                result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data, user_id=user_id)
                yield result

        except Exception:
            self.logger.info(f"获取{name}参赛号错误：{traceback.format_exc()}")

    def parse_wenguang(self, response):
        user_id = response.meta.get("user_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        card_num = response.meta.get("card_num", "")
        try:
            self.logger.info(f"{name}开始打码")
            content = json.loads(response.text)
            key = content.get("key", "")
            image = content.get("image", "")
            ocr = ddddocr.DdddOcr(beta=True)
            yzm = ocr.classification(image.replace("data:image/png;base64,", ""))
            post_data = {"certNo": card_num, "captchaValue": yzm, "captchaKey": key}
            url = "https://xm.xcmsports.com/api/charitable-service/marathonachievement/qryMyMarathonAchievementInfo"
            header = {
                "Host": "xm.xcmsports.com",
                "Accept": "application/json",
                "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
            }
            yield FormRequest(url, callback=self.parse_wg_raceno, errback=self.err_parse,
                              formdata=post_data, headers=header, dont_filter=True,
                              meta={"user_id": user_id, "card_num": card_num, 'handle_httpstatus_list': [400, 200],
                                    "serial_number": serial_number, "name": name})
        except Exception:
            self.logger.info(f"{name}打码错误：{traceback.format_exc()}")

    def parse_wg_raceno(self, response):
        user_id = response.meta.get("user_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        try:
            self.logger.info(f"获取{name}的参赛号")
            data_list = json.loads(response.text).get("data", {}).get("runnerPersonSubscribeList", [])
            r_name = ""
            no = ""
            project_name = ""
            for data in data_list:
                r_name = data.get("eventPlayName", "")
                project_name = data.get("projectName", "")
                if self.race_name in r_name:
                    no = data.get("playerNo", "")
                    break
            if no:
                result_data = {"race_id": self.race_id, "name": name,
                               "user_id": user_id, "race_no": no, "runner_status": "",
                               "race_name": r_name or self.race_name, "enroll_status": "",
                               "item_name": project_name, "sign_status": "",
                               "race_no_pic": ""}
                result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data,
                                        user_id=user_id)
            else:
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
            yield result
        except Exception:
            self.logger.info(f"获取{name}的参赛号错误：{traceback.format_exc()}")

    def parse_hefei(self, response):
        user_id = response.meta.get("user_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        card_num = response.meta.get("card_num", "")
        phone = response.meta.get("phone", "")
        try:
            self.logger.info(f"{name}开始打码")
            ocr = ddddocr.DdddOcr(beta=True)
            yzm = ocr.classification(response.body)
            post_data = {"userName": name, "userNumber": card_num, "mobilePhone": phone, "verify": yzm}
            url = "https://marathon.hefei.cc/mlsbaom/query.html"
            header = {
                "Host": "marathon.hefei.cc",
                "Content-Type": "application/x-www-form-urlencoded",
                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36",
                "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.",
                "Referer": "https://marathon.hefei.cc/mlsbaom/query.html"
            }
            yield FormRequest(url, callback=self.parse_hefei_raceno, errback=self.err_parse,
                              formdata=post_data, headers=header, dont_filter=True,
                              meta={"user_id": user_id, "card_num": card_num,
                                    "serial_number": serial_number, "name": name})
        except Exception:
            self.logger.info(f"{name}打码错误：{traceback.format_exc()}")

    def parse_hefei_raceno(self, response):
        user_id = response.meta.get("user_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        try:
            self.logger.info(f"获取{name}的参赛号")
            title_list = response.xpath("//div[@class='jfmeun']/label/text()").extract()
            title_list = [t.strip("：") for t in title_list]
            value_list = response.xpath("//div[@class='jfmeun']/span/text()").extract()
            value_list = [v.strip() for v in value_list]
            data_dict = dict(zip(title_list, value_list))
            if data_dict:
                result_data = {"race_id": self.race_id, "name": name,
                               "user_id": user_id, "race_no": data_dict.get("参赛编号", ""), "runner_status": "",
                               "race_name": self.race_name or self.race_name, "enroll_status": "",
                               "item_name": data_dict.get("报名项目", ""), "sign_status": "",
                               "race_no_pic": ""}
                result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data,
                                        user_id=user_id)
            else:
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
            yield result
        except Exception:
            self.logger.info(f"获取{name}的参赛号错误：{traceback.format_exc()}")

    def parse_weibu(self, response):
        user_id = response.meta.get("user_id", "")
        card_num = response.meta.get("card_num", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        try:
            self.logger.info(f"开始获取{name}的报名信息")
            data = json.loads(response.text).get("data", {}).get("data", [])
            exist_flag = False
            for d in data:
                if d.get("status", "") not in ["订单已取消", "审核不通过"]:
                    no = d.get("no", "")
                    group = d.get("package_name", "")
                    no_img = d.get("no_img", "")
                    status = d.get("status", "")
                    result_data = {"race_id": self.race_id, "name": name, "user_id": user_id, "race_no": no,
                                   "runner_status": status,
                                   "race_name": d.get("game_name", "") or self.race_name, "enroll_status": status, "item_name": group}
                    if no_img:
                        yield Request(no_img, callback=self.parse_pic, errback=self.err_parse, dont_filter=True,
                                      meta={"race_id": self.race_id, "user_id": user_id, "card_num": card_num, "serial_number": serial_number,
                                            "race_name": d.get("game_name", "") or self.race_name, "name": name, "result_data": result_data})
                    else:
                        result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data, user_id=user_id)
                        yield result
                    exist_flag = True

            if not data or not exist_flag:
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                yield result
        except Exception:
            self.logger.info(f"获取img_id错误：{traceback.format_exc()}")

    def parse_caochang(self, response):
        user_id = response.meta.get("user_id", "")
        card_num = response.meta.get("card_num", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        try:
            self.logger.info(f"开始获取{name}的报名信息")
            data_list = json.loads(response.text)
            if data_list:
                no = data_list[0].get("code", "")
                group = ""
                sub_data_list = data_list[0].get("data", [])
                for sub_data in sub_data_list:
                    if sub_data.get("label", "") == "组别":
                        group = sub_data.get("value", "")
                        break
                result_data = {"race_id": self.race_id, "name": name, "user_id": user_id, "race_no": no,
                               "runner_status": "", "race_name": self.race_name, "enroll_status": "", "item_name": group}
                no_img = data_list[0].get("pic", "")
                if no_img:
                    yield Request(no_img, callback=self.parse_pic, errback=self.err_parse, dont_filter=True,
                                  meta={"user_id": user_id, "card_num": card_num, "serial_number": serial_number,
                                        "name": name, "result_data": result_data})
                else:
                    result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data, user_id=user_id)
                    yield result
            else:
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                yield result
        except Exception:
            self.logger.info(f"获取img_id错误：{traceback.format_exc()}")

    def parse_ihuipao(self, response):
        user_id = response.meta.get("user_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        try:
            self.logger.info(f"开始获取{name}的报名信息")
            data = json.loads(response.text).get("data", [])
            if data:
                for d in data:
                    no = d.get("bib", "")
                    group = d.get("meta", {}).get("event", "") or d.get("event", {}).get("name", "")
                    result_data = {"race_id": self.race_id, "name": name, "user_id": user_id, "race_no": no, "race_no_pic": "",
                                   "runner_status": "", "race_name": self.race_name, "enroll_status": "", "item_name": group}
                    result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data, user_id=user_id)
                    yield result
            else:
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                yield result
        except Exception:
            self.logger.info(f"获取{name}的报名信息错误：{traceback.format_exc()}")

    def parse_zstong(self, response):
        user_id = response.meta.get("user_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        card_num = response.meta.get("card_num", "")
        try:
            self.logger.info(f"开始获取{name}的报名信息")
            data = json.loads(response.text).get("data", [])
            if data:
                for d in data:
                    no = d.get("matchNo", "")
                    group = d.get("groupName", "")
                    no_img = d.get("matchNoPic", "")
                    result_data = {"race_id": self.race_id, "name": name, "user_id": user_id, "race_no": no, "race_no_pic": "",
                                   "runner_status": "", "race_name": self.race_name, "enroll_status": "", "item_name": group}
                    if no_img:
                        yield Request(no_img, callback=self.parse_pic, errback=self.err_parse, dont_filter=True,
                                      meta={"user_id": user_id, "card_num": card_num, "serial_number": serial_number,
                                            "name": name, "result_data": result_data})
                    else:
                        result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data, user_id=user_id)
                        yield result
            else:
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                yield result
        except Exception:
            self.logger.info(f"获取{name}的报名信息错误：{traceback.format_exc()}")

    def parse_maxiaozhu(self, response):
        user_id = response.meta.get("user_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        card_num = response.meta.get("card_num", "")
        try:
            self.logger.info(f"开始获取{name}的报名信息")
            table = response.xpath("//table[@class='processforsuccinfotable']")
            if table:
                title_list = []
                value_list = []
                for tr in table.xpath(".//tr[not(@class)]"):
                    title_list.append("".join(tr.xpath("./td[@class='textleft']/text()").extract()).strip())
                    value_list.append("".join(tr.xpath("./td[@class='textright']/text()").extract()).strip())
                title_list = list(filter(lambda x: x != "", title_list))
                value_list = list(filter(lambda x: x != "", value_list))
                data_dict = dict(zip(title_list, value_list))
                result_data = {"race_id": self.race_id, "name": name, "user_id": user_id,
                               "race_no": f'{data_dict.get("分区", "")}{data_dict.get("参赛号", "")}',
                               "race_no_pic": "",
                               "runner_status": "", "race_name": self.race_name, "enroll_status": "",
                               "item_name": data_dict.get("参赛项目", "")}
                no_link = response.xpath("//td/a/img/@src").extract_first()
                if no_link:
                    no_img = f"https://jiande.zjim.org{no_link}"
                    yield Request(no_img, callback=self.parse_pic, errback=self.err_parse, dont_filter=True,
                                  meta={"user_id": user_id, "card_num": card_num, "serial_number": serial_number,
                                        "name": name, "result_data": result_data})
                else:
                    result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data,
                                            user_id=user_id)
                    yield result
            else:
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                yield result
        except Exception:
            self.logger.info(f"获取{name}的报名信息错误：{traceback.format_exc()}")

    def parse_saishiquan(self, response):
        user_id = response.meta.get("user_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        card_num = response.meta.get("card_num", "")
        header = response.meta.get("header", {})
        try:
            self.logger.info(f"开始获取{name}的报名信息")
            data = json.loads(response.text).get("data", [])
            for d in data:
                no = d.get("number", "")
                group = d.get("groupName", "")
                result_data = {"race_id": self.race_id, "name": name, "user_id": user_id, "race_no": no, "race_no_pic": "",
                               "runner_status": "", "race_name": self.race_name, "enroll_status": "", "item_name": group}
                no_img = f"https://www.saishiquan.cn/api/match/getCertificate?themeId=1004&groupName={group}"
                yield Request(no_img, callback=self.parse_saishiquan_pic_url, errback=self.err_parse, headers=header,
                              meta={"user_id": user_id, "card_num": card_num,
                                    "serial_number": serial_number, "name": name,
                                    "result_data": result_data})
            else:
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                yield result
        except Exception:
            self.logger.info(f"获取{name}的报名信息错误：{traceback.format_exc()}")

    def parse_saishiquan_pic_url(self, response):
        user_id = response.meta.get("user_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        card_num = response.meta.get("card_num", "")
        result_data = response.meta.get("result_data", {})
        try:
            self.logger.info(f"开始获取{name}的报名信息")
            url = json.loads(response.text).get("data", {}).get("directory", {}).get("numberedClothUrl", "")
            if url:
                yield Request(url, callback=self.parse_pic, errback=self.err_parse, dont_filter=True,
                              meta={"user_id": user_id, "card_num": card_num,
                                    "serial_number": serial_number, "name": name,
                                    "result_data": result_data})
            else:
                result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data, user_id=user_id)
                yield result
        except Exception:
            self.logger.info(f"获取{name}的报名信息错误：{traceback.format_exc()}")

    def parse_bojie(self, response):
        user_id = response.meta.get("user_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        card_num = response.meta.get("card_num", "")
        try:
            self.logger.info(f"开始获取{name}的报名信息")
            data = json.loads(response.text).get("runner", {})
            if data:
                no = data.get("bib", "")
                group = data.get("item", {}).get("title", "")
                no_img = json.loads(response.text).get("bib_image", "")
                result_data = {"race_id": self.race_id, "name": name, "user_id": user_id, "race_no": no, "race_no_pic": "",
                               "runner_status": "", "race_name": self.race_name, "enroll_status": "", "item_name": group}
                if no_img:
                    yield Request(no_img, callback=self.parse_pic, errback=self.err_parse, dont_filter=True,
                                  meta={"user_id": user_id, "card_num": card_num,
                                        "serial_number": serial_number, "name": name,
                                        "result_data": result_data})
                else:
                    result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data, user_id=user_id)
                    yield result
            else:
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                yield result
        except Exception:
            self.logger.info(f"获取{name}的报名信息错误：{traceback.format_exc()}")

    def parse_huayuan(self, response):
        user_id = response.meta.get("user_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        try:
            self.logger.info(f"开始获取{name}的报名信息")
            data_list = json.loads(response.text).get("data", [])
            if data_list:
                d_list = []
                for data in data_list:
                    no = data.get("no", "")
                    group = data.get("zb", "")
                    result_data = {"race_id": self.race_id, "name": name, "user_id": user_id, "race_no": no, "race_no_pic": "",
                                   "runner_status": "", "race_name": self.race_name, "enroll_status": "", "item_name": group}
                    d_list.append(result_data)
                result = self.send_data(resp=response, serial_number=serial_number, result_data=d_list, user_id=user_id)
                yield result
            else:
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                yield result
        except Exception:
            self.logger.info(f"获取{name}的报名信息错误：{traceback.format_exc()}")

    def parse_inrace(self, response):
        user_id = response.meta.get("user_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        try:
            self.logger.info(f"开始获取{name}的报名信息")
            data = json.loads(response.text).get("data", {}).get("fields", {})
            if data:
                no = data.get("participant_code", "")
                group = data.get("project", "")
                result_data = {"race_id": self.race_id, "name": name, "user_id": user_id, "race_no": no, "race_no_pic": "",
                               "runner_status": "", "race_name": self.race_name, "enroll_status": "", "item_name": group}
                img_url = data.get("bib_image", "")
                if img_url:
                    yield Request(img_url, callback=self.parse_pic, errback=self.err_parse, dont_filter=True,
                                  meta={"user_id": user_id, "serial_number": serial_number,
                                        "name": name, "result_data": result_data})
                else:
                    result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data, user_id=user_id)
                    yield result
            else:
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                yield result
        except Exception:
            self.logger.info(f"获取{name}的报名信息错误：{traceback.format_exc()}")

    def parse_umaysports(self, response):
        user_id = response.meta.get("user_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        try:
            self.logger.info(f"开始获取{name}的报名信息")
            data_list = []
            data = json.loads(response.text).get("data", {}).get("list", [])
            if data:
                for d in data:
                    no = d.get("allocation", "")
                    group = d.get("event_name", "")
                    apply_status = d.get("apply_status_title", "")
                    result_data = {"race_id": self.race_id, "name": name, "user_id": user_id, "race_no": no, "race_no_pic": "",
                                   "runner_status": apply_status, "race_name": d.get("game_name", "") or self.race_name,
                                   "enroll_status": apply_status, "item_name": group}
                    data_list.append(result_data)
                result = self.send_data(resp=response, serial_number=serial_number, result_data=data_list, user_id=user_id)
                yield result
            else:
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                yield result
        except Exception:
            self.logger.info(f"获取{name}的报名信息错误：{traceback.format_exc()}")

    def parse_queenrun(self, response):
        user_id = response.meta.get("user_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        try:
            self.logger.info(f"开始获取{name}的报名信息")
            data = json.loads(response.text).get("data", {}).get("list", [])
            if data:
                for d in data:
                    no = d.get("competeNumber", "")
                    group = d.get("courseName", "")
                    r_name = d.get("competitionName", "")
                    u_name = d.get("userName", "")
                    if self.race_name in r_name and no:
                        result_data = {"race_id": self.race_id, "name": u_name, "user_id": user_id, "race_no": no, "race_no_pic": "",
                                       "runner_status": "", "race_name": r_name,
                                       "enroll_status": "", "item_name": group}
                        result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data, user_id=user_id)
                        yield result
                        break
            else:
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                yield result
        except Exception:
            self.logger.info(f"获取{name}的报名信息错误：{traceback.format_exc()}")

    def parse_jdgo(self, response):
        user_id = response.meta.get("user_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        try:
            self.logger.info(f"开始获取{name}的报名信息")
            data = json.loads(response.text).get("data", [])
            if data:
                race_list = []
                for d in data:
                    no = d.get("bibNumber", "")
                    group = d.get("competitionCategoryName", "")
                    r_name = d.get("activityName", "")
                    u_name = d.get("playerName", "")
                    result_data = {"race_id": self.race_id, "name": u_name, "user_id": user_id, "race_no": no, "race_no_pic": "",
                                   "runner_status": "", "race_name": r_name,
                                   "enroll_status": "", "item_name": group}
                    race_list.append(result_data)
                result = self.send_data(resp=response, serial_number=serial_number, result_data=race_list, user_id=user_id)
                yield result
            else:
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                yield result
        except Exception:
            self.logger.info(f"获取{name}的报名信息错误：{traceback.format_exc()}")

    def parse_saixun(self, response):
        serial_number = response.meta.get("serial_number", "")
        user_id = response.meta.get("user_id", "")
        name = response.meta.get("name", "")
        proxy_url = response.request.meta.get("proxy", "")
        proxy_pre = response.request.meta.get("proxy_pre", "")
        try:
            self.logger.info(f"开始获取{name}的报名信息")
            if response.xpath("//td[@class='no-result']"):
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                yield result
            else:
                race_no_list = []
                tr_list = response.xpath("//div[@class='appliers-wrap']/table/tbody/tr")
                for tr in tr_list:
                    race_no_pic = ""
                    race_no = tr.xpath("./td[@class='t1']/text()").extract_first().strip()
                    race_group = tr.xpath("./td[@class='t6']/text()").extract_first().strip()
                    r_name = tr.xpath("./td[@class='t5']//text()").extract_first().strip()
                    if tr.xpath("./td[@class='t8']//a[@class='downloadNumberCloth']"):
                        pic_name = f'{calc_str_md5(f"{race_no}_{self.race_id}")}.jpg'
                        dir_path = os.path.join(file_path, self.name_first)
                        if not os.path.exists(dir_path):
                            os.makedirs(dir_path)
                        save_path = os.path.join(dir_path, pic_name)
                        pic_flag = SignChrome().get_pic1(response.url, dir_path, save_path, proxy_url, proxy_pre)
                        if pic_flag:
                            upload_path = f"flow/{self.race_id}/{user_id}/raceno/{pic_name}"
                            upload_flag = upload_file(save_path, upload_path)
                            if upload_flag:
                                self.logger.info(f"{save_path}上传成功：{upload_path}")
                                race_no_pic = upload_path
                            else:
                                self.logger.info(f"{save_path}上传失败：{upload_path}")
                    result_data = {"race_id": self.race_id, "name": name, "user_id": user_id, "race_no": race_no, "race_no_pic": race_no_pic,
                                   "runner_status": "", "race_name": r_name, "enroll_status": "", "item_name": race_group}
                    race_no_list.append(result_data)
                result = self.send_data(resp=response, serial_number=serial_number, result_data=race_no_list, user_id=user_id)
                yield result
        except Exception:
            self.logger.info(f"获取{name}的报名信息错误：{traceback.format_exc()}")

    def parse_biaodan(self, response):
        try:
            self.logger.info(f"开始获取FRMID")
            frm_id = response.xpath("//input[@name='FRMID']/@value").extract_first().strip()
            url = "https://biaodan100.com/web/pubdata/query?SHORTID=qscfse"
            for user in self.user_list:
                serial_number = user.get("serialNumber", "")
                name = user.get("name", "")
                user_id = user.get("user_id", "")
                card_num = user.get("card_num", "")
                priority = int(user.get("priority_level", 0))
                data = {"FRMID":frm_id,"F3":name,"F5":card_num,"SHORTID":"qscfse","PREORNEXT":"FIRST","PAGEINFO":{},"PAGESIZE":10}
                header = {
                    "Host": "biaodan100.com",
                    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36",
                    "Content-Type": "application/json; charset=UTF-8",
                    "Accept": "application/json, text/javascript, */*; q=0.01"
                }
                yield Request(url, callback=self.parse_biaodan_raceno, errback=self.err_parse, method="POST",
                              body=json.dumps(data), headers=header, dont_filter=True, priority=priority,
                              meta={"user_id": user_id, "serial_number": serial_number, "name": name})
        except Exception:
            self.logger.info(f"获取FRMID错误：{traceback.format_exc()}")

    def parse_cqcjh(self, response):
        try:
            proxy_url = response.request.meta.get("proxy", "")
            proxy_pre = response.request.meta.get("proxy_pre", "")
            for user in self.user_list:
                serial_number = user.get("serialNumber", "")
                name = user.get("name", "")
                self.logger.info(f"开始获取{name}的参赛号")
                user_id = user.get("user_id", "")
                card_num = user.get("card_num", "")
                priority = int(user.get("priority_level", 0))
                i = 0
                while i < 1:
                    try:
                        html = SignChrome().get_sign(response.url, card_num, proxy_url, proxy_pre)
                        if html:
                            data_dict = {}
                            tree = etree.HTML(html)
                            div_list = tree.xpath("//div[@id='t_signup']/div")
                            for div in div_list:
                                name = "".join(div.xpath("./span[@class='l']//text()")).strip()
                                value = "".join(div.xpath("./span[@class='r']//text()")).strip()
                                if name:
                                    data_dict[name] = value
                            result_data = {"race_id": self.race_id, "name": data_dict.pop("选手姓名", ""), "user_id": user_id,
                                           "race_no": data_dict.get("参赛号码", ""), "runner_status": data_dict.pop("状态", ""),
                                           "race_name": self.race_name, "enroll_status": data_dict.pop("状态", ""),
                                           "item_name": data_dict.pop("参赛项目", "")}
                            result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data,
                                                    user_id=user_id)
                            yield result
                            break
                        else:
                            i += 1
                            proxy_url = self.get_proxy() if self.use_proxy else ""
                    except Exception:
                        i += 1
                        proxy_url = self.get_proxy() if self.use_proxy else ""
                else:
                    result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                    yield result
                proxy_url = self.get_proxy() if self.use_proxy else ""
        except Exception:
            self.logger.info(f"获取参赛号错误：{traceback.format_exc()}")

    def parse_yichafen(self, response):
        try:
            header = response.meta.get("header", {})
            self.logger.info(f"开始获取url")
            link = "".join(re.findall(r"\$.post\(\"(.*?)\",", response.text)).strip()
            if link:
                url = response.urljoin(link)
                for user in self.user_list:
                    serial_number = user.get("serialNumber", "")
                    name = user.get("name", "")
                    user_id = user.get("user_id", "")
                    card_num = user.get("card_num", "")
                    priority = int(user.get("priority_level", 0))
                    data = {"s_xingming": name, "s_zhengjianhousiwei": card_num[-4:]}
                    header = {
                        "Host": "u5y67z3d.yichafen.com",
                        "X-Requested-With": "XMLHttpRequest",
                        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36",
                        "Accept": "*/*",
                        "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
                        "Referer": "https://u5y67z3d.yichafen.com/qz/1546Xz7mxt",
                        "Cookie": "PHPSESSID=g0b511kl4detl48tnmujtpf3b6"
                    }
                    yield FormRequest(url, callback=self.parse_yichafen_race, errback=self.err_parse, headers=header,
                                      formdata=data, dont_filter=True, priority=priority,
                                      meta={"header": header, "serial_number": serial_number,
                                            "user_id": user_id, "name": name})
        except Exception:
            self.logger.info(f"获取url错误：{traceback.format_exc()}")

    def parse_yichafen_race(self, response):
        try:
            self.logger.info(f"开始获取FRMID")
            header = response.meta.get("header", {})
            user_id = response.meta.get("user_id", "")
            serial_number = response.meta.get("serial_number", "")
            name = response.meta.get("name", "")
            link = json.loads(response.text).get("url", "")
            if link:
                url = response.urljoin(link)
                yield Request(url, callback=self.parse_yichafen_raceno, errback=self.err_parse,
                              headers=header, dont_filter=True,
                              meta={"user_id": user_id, "serial_number": serial_number, "name": name})
            else:
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                yield result
        except Exception:
            self.logger.info(f"获取FRMID错误：{traceback.format_exc()}")

    def parse_yichafen_raceno(self, response):
        header = response.meta.get("header", {})
        user_id = response.meta.get("user_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        try:
            self.logger.info(f"开始获取{name}的参赛号")
            title_list = response.xpath("//div[@id='result_data_table']//td[@class='left_cell']//text()").extract()
            title_list = filter(lambda x:x!="", [t.strip() for t in title_list])
            value_list = response.xpath("//div[@id='result_data_table']//td[@class='right_cell']//text()").extract()
            value_list = filter(lambda x:x!="", [t.strip() for t in value_list])
            data_dict = dict(zip(title_list, value_list))

            result_data = {"race_id": self.race_id, "name": name, "user_id": user_id, "race_no": data_dict.get("参赛号", ""),
                           "runner_status": "", "race_name": self.race_name, "enroll_status": "",
                           "item_name": data_dict.get("参赛项目", "")}
            result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data, user_id=user_id)
            yield result
        except Exception:
            self.logger.info(f"获取获取{name}的参赛号错误：{traceback.format_exc()}")

    def parse_xhrace(self, response):
        try:
            self.logger.info(f"开始获取sreachRule")
            event_id = response.meta.get("event_id", "")
            header = response.meta.get("header", {})
            rule = json.loads(response.text).get("data", {}).get("sreachRule", "")
            for user in self.user_list:
                serial_number = user.get("serialNumber", "")
                name = user.get("name", "")
                user_id = user.get("user_id", "")
                card_num = user.get("card_num", "")
                priority = int(user.get("priority_level", 0))
                url = f"https://www.xhrace.com/api/event-mgr/eventParticipantList/frontSearch?eventId={event_id}&keyword={card_num}&sreachRule={rule}"
                yield Request(url, callback=self.parse_xhrace_raceno, errback=self.err_parse,
                              headers=header, dont_filter=True, priority=priority,
                              meta={"user_id": user_id, "serial_number": serial_number, "name": name,
                                    "event_id": event_id, "card_num": card_num})
        except Exception:
            self.logger.info(f"获取sreachRule错误：{traceback.format_exc()}")

    def parse_xhrace_raceno(self, response):
        user_id = response.meta.get("user_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        event_id = response.meta.get("event_id", "")
        card_num = response.meta.get("card_num", "")
        try:
            self.logger.info(f"开始获取{name}的赛事号")
            data_list = json.loads(response.text).get("data", [])
            if not data_list:
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                yield result
            else:
                bib = ",".join(data_list[0].get("bibNumbers", []))
                group = data_list[0].get("projectName", "")
                result_data = {"race_id": self.race_id, "name": name, "user_id": user_id, "race_no": bib,
                               "runner_status": "", "race_name": self.race_name, "enroll_status": "",
                               "item_name": group}
                cert_url = f"https://www.xhrace.com/api/statistics/front/electronImg/{event_id}/{card_num}"
                yield Request(cert_url, callback=self.parse_pic, errback=self.err_parse, dont_filter=True,
                              meta={"user_id": user_id, "serial_number": serial_number,
                                    "name": name, "result_data": result_data})
        except Exception:
            self.logger.info(f"获取{name}的赛事号：{traceback.format_exc()}")

    def parse_running(self, response):
        try:
            self.logger.info(f"开始获取参数")
            slug = "".join(re.findall(r"{slug:'(.*)?'", response.text)).strip()
            r_id = "".join(re.findall(r"race_id:(.*)?}", response.text)).strip()
            if "this" in r_id:
                r_id = "".join(re.findall(r"race_id:(\d+)?,", response.text)).strip()
            for user in self.user_list:
                serial_number = user.get("serialNumber", "")
                name = user.get("name", "")
                user_id = user.get("user_id", "")
                card_num = user.get("card_num", "")
                priority = int(user.get("priority_level", 0))
                if slug:
                    data = {"slug": slug,"id_card": card_num,"name": "", "phone": "", "race_id": int(r_id)}
                    url = "https://new-time.running8.com/query/bib"
                    host = "new-time.running8.com"
                else:
                    data = {"id_card": card_num, "race_id": int(r_id)}
                    url = "https://new.running8.com/query/runner/post"
                    host = "new.running8.com"
                header = {
                    "Host": host,
                    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36",
                    "Content-Type": "application/json",
                    "Accept": "*/*"
                }
                yield Request(url, callback=self.parse_running_raceno, errback=self.err_parse, method="POST",
                              body=json.dumps(data), dont_filter=True, headers=header, priority=priority,
                              meta={"user_id": user_id, "serial_number": serial_number, "name": name})
        except Exception:
            self.logger.info(f"获取参数错误：{traceback.format_exc()}")

    def parse_baidian(self, response):
        try:
            self.logger.info(f"开始获取{self.race_name}的赛事id")
            r_id = "".join(re.findall(r"querybibnumbers.jsf\?match=(\d+)&fzid=", response.text)).strip()
            if r_id:
                for user in self.user_list:
                    serial_number = user.get("serialNumber", "")
                    name = user.get("name", "")
                    user_id = user.get("user_id", "")
                    card_num = user.get("card_num", "")
                    priority = int(user.get("priority_level", 0))
                    url = f"{response.url}?match={r_id}&fzid=&qr={card_num}"
                    yield Request(url, callback=self.parse_baidian_raceno, errback=self.err_parse, dont_filter=True,
                                  priority=priority, meta={"user_id": user_id,"serial_number": serial_number, "name": name})
        except Exception:
            self.logger.info(f"获取{self.race_name}的赛事id错误：{traceback.format_exc()}")

    def parse_baidian_raceno(self, response):
        user_id = response.meta.get("user_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        try:
            self.logger.info(f"开始获取{name}的赛事号")
            if "没有查询到" in "".join(response.xpath("//i[@class='fontcn']/text()").extract()):
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                yield result
            else:
                title_list = response.xpath("//table[@class='processforsuccinfotable']/tbody/tr/td[@class='textleft']/text()").extract()
                title_list = [t.strip() for t in title_list]
                value_list = response.xpath("//table[@class='processforsuccinfotable']/tbody/tr/td[@class='textright']/text()").extract()
                value_list = [v.strip() for v in value_list]
                data_dict = dict(zip(title_list, value_list))
                result_data = {"race_id": self.race_id, "name": name, "user_id": user_id, "race_no": data_dict.get("参赛号", ""),
                               "runner_status": "", "race_name": self.race_name, "enroll_status": "",
                               "item_name": data_dict.get("参赛项目", "")}
                result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data, user_id=user_id)
                yield result
        except Exception:
            self.logger.info(f"获取{name}的赛事号：{traceback.format_exc()}")

    def parse_running_raceno(self, response):
        user_id = response.meta.get("user_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        try:
            self.logger.info(f"开始获取{name}的参赛号")
            content = json.loads(response.text).get("runner", {})
            if content:
                result_data = {"race_id": self.race_id, "name": name, "user_id": user_id, "race_no": content.get("bib", ""),
                               "runner_status": "", "race_name": self.race_name, "enroll_status": "",
                               "item_name": content.get("item", {}).get("title", "")}
                if json.loads(response.text).get("bib_image", ""):
                    img_url = json.loads(response.text).get("bib_image", "")
                    yield Request(img_url, callback=self.parse_pic, errback=self.err_parse, dont_filter=True,
                                  meta={"user_id": user_id, "serial_number": serial_number,
                                        "name": name, "result_data": result_data})
                else:
                    result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data, user_id=user_id)
                    yield result
            else:
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                yield result
        except Exception:
            self.logger.info(f"获取{name}的参赛号错误：{traceback.format_exc()}")

    def parse_beedancing(self, response):
        user_id = response.meta.get("user_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        try:
            self.logger.info(f"开始获取{name}的参赛号")
            content = json.loads(response.text).get("data", {})
            if content:
                result_data = {"race_id": self.race_id, "name": name, "user_id": user_id, "race_no": content.get("cno", ""),
                               "runner_status": "", "race_name": self.race_name, "enroll_status": "",
                               "item_name": content.get("group", "")}
                result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data, user_id=user_id)
                yield result
            else:
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                yield result
        except Exception:
            self.logger.info(f"获取{name}的参赛号错误：{traceback.format_exc()}")

    def parse_saizhongsai(self, response):
        user_id = response.meta.get("user_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        try:
            self.logger.info(f"开始获取{name}的参赛号")
            content = json.loads(response.text).get("data", {})
            if content:
                result_data = {"race_id": self.race_id, "name": name, "user_id": user_id, "race_no": content.get("race", {}).get("raceCode", ""),
                               "runner_status": "", "race_name": self.race_name, "enroll_status": "",
                               "item_name": content.get("group", "半程马拉松")}
                result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data, user_id=user_id)
                yield result
            else:
                msg = json.loads(response.text).get("msg", "")
                result_data = {"msg": "未查到报名信息"}
                if "没有报名记录" not in msg:
                    result_data = {"msg": "登录过期"}
                result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data, user_id=user_id)
                yield result
        except Exception:
            self.logger.info(f"获取{name}的参赛号错误：{traceback.format_exc()}")

    def parse_moran(self, response):
        user_id = response.meta.get("user_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        des_key = response.meta.get("des_key", "")
        app_id = response.meta.get("app_id", "")
        p_data = response.meta.get("post_data", {})
        header = response.meta.get("header", {})
        try:
            self.logger.info(f"开始获取{name}的参赛号")
            content = json.loads(response.text).get("text", "")
            content = json.loads(self.decryptDes(des_key, content))
            data_list = content.get("data", [])
            if data_list:
                for data in data_list:
                    d_list = data.get("scoredata", {}).get("showrow", [])
                    data_dict = {"赛事名称": d_list[0].get("valcenter", self.race_name)}
                    for d in d_list:
                        data_dict[d.get("title", "")] = d.get("val", "")
                    result_data = {"race_id": self.race_id, "name": data_dict.get("姓名", name),
                                   "user_id": user_id, "race_no": f'{data_dict.get("分区", "")}{data_dict.get("参赛号", "")}',
                                   "runner_status": "", "race_name": data_dict.get("赛事名称", ""), "enroll_status": "",
                                   "item_name": data_dict.get("比赛项目", "")}
                    cert_data_list = data.get("scoredata", {}).get("certificates", [])
                    img_flag = ""
                    if cert_data_list:
                        for cert_data in cert_data_list:
                            if cert_data.get("name", "") == "参赛号码布":
                                img_flag = cert_data.get("typeflag", "")
                                break
                    if img_flag:
                        p_data.pop("paramobjid", "")
                        p_data.pop("paramval1", "")
                        p_data["typeflag"] = img_flag
                        encrypt_data = self.encryptDes(des_key, json.dumps(p_data))
                        post_data = {"appid": app_id, "text": encrypt_data}
                        url = "https://moran.zjim.org/api/routepost/signupinquiry/certificatedown"
                        yield Request(url=url, callback=self.parse_moran_img, dont_filter=True,
                                      errback=self.err_parse, method="POST", body=json.dumps(post_data), headers=header,
                                      meta={"user_id": user_id, "des_key": des_key,
                                            "name": name, "serial_number": serial_number,
                                            "result_data": result_data})
                    else:
                        result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data,
                                                user_id=user_id)
                        yield result
            else:
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                yield result
        except Exception:
            self.logger.info(f"获取{name}的参赛号错误：{traceback.format_exc()}")

    def parse_moran_img(self, response):
        user_id = response.meta.get("user_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        des_key = response.meta.get("des_key", "")
        result_data = response.meta.get("result_data", {})
        try:
            self.logger.info(f"获取{name}的号码簿信息")
            content = json.loads(response.text).get("text", "")
            content = json.loads(self.decryptDes(des_key, content))
            cert_url = content.get("certificateurl", "")
            if cert_url:
                yield Request(cert_url, callback=self.parse_pic, errback=self.err_parse, dont_filter=True,
                              meta={"user_id": user_id, "serial_number": serial_number,
                                    "name": name, "result_data": result_data})
            else:
                result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data,
                                        user_id=user_id)
                yield result
        except Exception:
            self.logger.info(f"获取{name}的号码簿信息错误：{traceback.format_exc()}")

    def parse_aituye(self, response):
        user_id = response.meta.get("user_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        try:
            self.logger.info(f"开始获取{name}的参赛号链接")
            link = response.xpath("//td/a/@href").extract_first()
            if link:
                url = response.urljoin(link.strip())
                yield Request(url=url, callback=self.parse_aituye_raceno, dont_filter=True, errback=self.err_parse,
                              meta={"user_id": user_id, "name": name, "serial_number": serial_number})
            else:
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                yield result
        except Exception:
            self.logger.info(f"获取{name}的参赛号链接错误：{traceback.format_exc()}")

    def parse_aituye_raceno(self, response):
        user_id = response.meta.get("user_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        try:
            self.logger.info(f"开始获取{name}的参赛号")
            title_list = response.xpath("//td[@class='STYLE2']/strong/text()").extract()
            title_list = [t.strip().replace("：", "") for t in title_list]
            value_list = response.xpath("//td[@class='STYLE2']/text()").extract()
            value_list = [v.strip().replace('"', "") for v in value_list]
            value_list = list(filter(lambda x: x != "", value_list))
            data_dict = dict(zip(title_list, value_list))
            result_data = {"race_id": self.race_id, "name": name, "user_id": user_id, "race_no": data_dict.get("参赛号码", ""),
                           "runner_status": "", "race_name": self.race_name, "enroll_status": "",
                           "item_name": data_dict.get("赛程说明", "")}
            result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data,
                                    user_id=user_id)
            yield result
        except Exception:
            self.logger.info(f"获取{name}的参赛号错误：{traceback.format_exc()}")

    def parse_jifeng(self, response):
        user_id = response.meta.get("user_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        try:
            self.logger.info(f"开始获取{name}的参赛号")
            content = json.loads(response.text).get("data", {})
            if content:
                group = ""
                no = ""
                data_list = content.get("baseinfo", [])
                for data in data_list:
                    if "参赛项目" in data.get("label", ""):
                        group = data.get("text", "")
                    if "参赛号码" in data.get("label", ""):
                        no = data.get("text", "")
                result_data = {"race_id": self.race_id, "name": name, "user_id": user_id, "race_no": no,
                               "runner_status": "", "race_name": self.race_name, "enroll_status": "",
                               "item_name": group}
                result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data,
                                        user_id=user_id)
                yield result
            else:
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                yield result
        except Exception:
            self.logger.info(f"获取{name}的参赛号错误：{traceback.format_exc()}")

    def parse_runnar(self, response):
        user_id = response.meta.get("user_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        try:
            self.logger.info(f"开始获取{name}的参赛号")
            content = json.loads(response.text).get("data", {}).get("regInfo", {})
            if content:
                result_data = {"race_id": self.race_id, "name": name, "user_id": user_id, "race_no": content.get("userReginfoBib", ""),
                               "runner_status": "", "race_name": self.race_name, "enroll_status": "",
                               "item_name": content.get("matchProjectName", "")}
                result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data, user_id=user_id)
                yield result
            else:
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                yield result
        except Exception:
            self.logger.info(f"获取{name}的参赛号错误：{traceback.format_exc()}")

    def parse_iborun(self, response):
        user_id = response.meta.get("user_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        try:
            self.logger.info(f"开始获取{name}的参赛号")
            data_list = json.loads(response.text).get("rows", [])
            if data_list:
                race_list = []
                for data in data_list:
                    result_data = {"race_id": self.race_id, "name": data.get("trueName", ""), "user_id": user_id, "race_no": data.get("no", ""),
                                   "runner_status": "", "race_name": data.get("gameName", ""), "enroll_status": "",
                                   "item_name": data.get("gameClassifyName", "")}
                    race_list.append(result_data)
                result = self.send_data(resp=response, serial_number=serial_number, result_data=race_list, user_id=user_id)
                yield result
            else:
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                yield result
        except Exception:
            self.logger.info(f"获取{name}的参赛号错误：{traceback.format_exc()}")

    def parse_guanghan(self, response):
        user_id = response.meta.get("user_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        try:
            self.logger.info(f"开始获取{name}的参赛号")
            root = ET.fromstring(response.text)
            msg = root.find('.//Message').text
            if msg == "ok":
                html = root.find('.//htmltext').text
                tree = etree.HTML(html)
                title_list = tree.xpath("//td[@class='tdText']/text()")
                title_list = [str(t) for t in title_list]
                value_list = tree.xpath("//td[@class='tdValue']/text()")
                value_list = [str(v) for v in value_list]
                data = dict(zip(title_list, value_list))
                result_data = {"race_id": self.race_id, "name": data.get("姓名", name), "user_id": user_id, "race_no": data.get("参赛号码", ""),
                               "runner_status": data.get("抽签状态", ""), "race_name": self.race_name, "enroll_status": data.get("抽签状态", ""),
                               "item_name": data.get("组别", "")}
                result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data, user_id=user_id)
                yield result
            else:
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                yield result
        except Exception:
            self.logger.info(f"获取{name}的参赛号错误：{traceback.format_exc()}")

    def parse_xtibo(self, response):
        user_id = response.meta.get("user_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        try:
            self.logger.info(f"开始获取{name}的参赛号")
            content = "".join(re.findall(r"var field = (.*)?;", response.text)) or "".join(re.findall(r"var details = (.*)?;", response.text))
            if content in ["null", "[]"]:
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                yield result
            else:
                group_name = ""
                race_no = ""
                cert_url = ""
                content = json.loads(content)
                if isinstance(content, dict):
                    race_no = content.get("plateNo", "")
                    cert_url = content.get("certUrl", "")
                elif isinstance(content, list):
                    race_no = content[0].get("plateNo", "")
                    group_name = content[0].get("group", "")
                    cert_url = content[0].get("certUrl", "")
                result_data = {"race_id": self.race_id, "name": name, "user_id": user_id, "race_no": race_no,
                               "runner_status": "", "race_name": self.race_name, "enroll_status": "",
                               "item_name": group_name}
                if cert_url:
                    yield Request(cert_url, callback=self.parse_pic, errback=self.err_parse, dont_filter=True,
                                  meta={"user_id": user_id, "serial_number": serial_number,
                                        "name": name, "result_data": result_data})
                else:
                    result_dict = {"serialNumber": self.serialNumber, "webType": self.name_first,
                                   "crawlerType": self.name_second, "data": str(result_data)}
                    result = self.result_item_assembler(response)
                    result['result_data'] = result_dict
                    yield result
        except Exception:
            self.logger.info(f"获取{name}的参赛号错误：{traceback.format_exc()}")

    def parse_swordfish(self, response):
        user_id = response.meta.get("user_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        card_num = response.meta.get("card_num", "")
        try:
            self.logger.info(f"开始获取{name}的报名信息")
            if "GetPlayerBaseInfo" in response.url:
                content = json.loads(response.text)
                rows = content.get("data", [])
                if not rows:
                    result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                    yield result
                else:
                    for r in rows:
                        race_no = r.get("参赛号", "")
                        race_group = r.get("参赛项目", "") or r.get("组别", "")
                        result_data = {"race_id": self.race_id, "name": name, "user_id": user_id, "race_no": race_no,
                                       "runner_status": "", "race_name": self.race_name, "enroll_status": "",
                                       "item_name": race_group}
                        img_url = r.get("img", "")
                        if img_url:
                            yield Request(url=img_url, callback=self.parse_pic, dont_filter=True,
                                          errback=self.err_parse,
                                          meta={"user_id": user_id, "card_num": card_num, "result_data": result_data,
                                                "name": name, "serial_number": serial_number})
                        else:
                            result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data, user_id=user_id)
                            yield result
            else:
                race_code = json.loads(response.text).get("data", {}).get("RaceCode", "")
                header = {
                    "X-Race-Code": race_code
                }
                for user in self.user_list:
                    serial_number = user.get("serialNumber", "")
                    name = user.get("name", "")
                    user_id = user.get("user_id", "")
                    card_num = user.get("card_num", "")
                    priority = int(user.get("priority_level", 0))
                    url = f"http://39.105.11.100:6601/api/OffRoad/GetPlayerBaseInfo/{card_num}"
                    yield Request(url, callback=self.parse_swordfish, errback=self.err_parse,
                                  headers=header, dont_filter=True, priority=priority,
                                  meta={"user_id": user_id, "card_num": card_num,
                                        "serial_number": serial_number, "name": name})
        except Exception:
            self.logger.info(f"获取{name}的报名信息错误：{traceback.format_exc()}")
    #
    # def parse_luojiweiye(self, response):
    #     race_id = response.meta.get("race_id", "")
    #     user_id = response.meta.get("user_id", "")
    #     race_name = response.meta.get("race_name", "")
    #     name = response.meta.get("name", "")
    #     try:
    #         self.logger.info(f"开始获取{name}的报名信息")
    #         data_list = json.loads(response.text).get("data", [])
    #         if data_list:
    #             data = data_list.pop(0)
    #             value = data.get("value", "")
    #             group_name = data.get("name", "")
    #             url = f"https://sport.luojiweiye.com/api/web/players?activity_id=4377&package_id={value}&page=1&page_size=20&sex=&real_name={name}&age_range=&user_id="
    #             yield Request(url, callback=self.parse_luojiweiye_raceno, errback=self.err_parse,
    #                           dont_filter=True,
    #                           meta={"race_id": race_id, "user_id": user_id, "data_list": data_list,
    #                                 "race_name": race_name, "name": name, "group_name": group_name})
    #         else:
    #             result = self.result_item_assembler(response)
    #             result_dict = {"serialNumber": self.serialNumber, "webType": self.name_first,
    #                            "crawlerType": self.name_second, "data": str({"msg": "未查到报名信息"})}
    #             result['result_data'] = result_dict
    #             yield result
    #     except Exception:
    #         self.logger.info(f"获取{name}的报名信息错误：{traceback.format_exc()}")
    #
    # def parse_luojiweiye_raceno(self, response):
    #     race_id = response.meta.get("race_id", "")
    #     user_id = response.meta.get("user_id", "")
    #     race_name = response.meta.get("race_name", "")
    #     name = response.meta.get("name", "")
    #     group_name = response.meta.get("group_name", "")
    #     data_list = response.meta.get("data_list", [])
    #     race_no_list = response.meta.get("race_no_list", [])
    #     try:
    #         self.logger.info(f"开始获取{name}的raceno")
    #         r_data_list = json.loads(response.text).get("data", {}).get("data", [])
    #         for data in r_data_list:
    #             race_no = data.get("no", "")
    #             result_data = {"race_id": race_id, "name": name, "user_id": user_id, "race_no": race_no,
    #                            "runner_status": "", "race_name": race_name, "enroll_status": "",
    #                            "item_name": group_name}
    #             race_no_list.append(result_data)
    #         if data_list:
    #             data = data_list.pop(0)
    #             value = data.get("value", "")
    #             group_name = data.get("name", "")
    #             url = f"https://sport.luojiweiye.com/api/web/players?activity_id=4377&package_id={value}&page=1&page_size=20&sex=&real_name={name}&age_range=&user_id="
    #             yield Request(url, callback=self.parse_luojiweiye_raceno, errback=self.err_parse,
    #                           dont_filter=True,
    #                           meta={"race_id": race_id, "user_id": user_id, "data_list": data_list, "race_no_list": race_no_list,
    #                                 "race_name": race_name, "name": name, "group_name": group_name})
    #         else:
    #             result_dict = {"serialNumber": self.serialNumber, "webType": self.name_first,
    #                            "crawlerType": self.name_second, "data": str(race_no_list)}
    #             result = self.result_item_assembler(response)
    #             result['result_data'] = result_dict
    #             yield result
    #     except Exception:
    #         self.logger.info(f"获取{name}的报名信息错误：{traceback.format_exc()}")

    def parse_spoorts(self, response):
        serial_number = response.meta.get("serial_number", "")
        user_id = response.meta.get("user_id", "")
        name = response.meta.get("name", "")
        try:
            self.logger.info(f"开始获取{name}的报名信息")
            content = json.loads(response.text).get("data", {})
            if not content:
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                yield result
            else:
                r_name = content.get("name", "")
                race_group = content.get("pre_enroll_info", {}).get("subject_name", "")
                area_code = content.get("pre_enroll_info", {}).get("start_area_code", "")
                race_number = content.get("pre_enroll_info", {}).get("race_number", "")
                race_no = race_number if area_code is None else f"{area_code}{race_number}"
                result_data = {"race_id": self.race_id, "name": name, "user_id": user_id, "race_no": race_no,
                               "runner_status": "", "race_name": r_name, "enroll_status": "",
                               "item_name": race_group}
                result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data, user_id=user_id)
                yield result
        except Exception:
            self.logger.info(f"获取{name}的报名信息错误：{traceback.format_exc()}")

    def parse_biaodan_raceno(self, response):
        user_id = response.meta.get("user_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        try:
            self.logger.info(f"开始获取{name}的报名信息")
            content = json.loads(response.text)
            rows = content.get("rows", [])
            if not rows:
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                yield result
            else:
                race_no = rows[0].get("F2", "")
                race_group = rows[0].get("F1", "")

                result_data = {"race_id": self.race_id, "name": name, "user_id": user_id, "race_no": race_no,
                               "runner_status": "", "race_name": self.race_name, "enroll_status": "", "item_name": race_group}
                result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data, user_id=user_id)
                yield result
        except Exception:
            self.logger.info(f"获取{name}的报名信息错误：{traceback.format_exc()}")

    def parse_wbs(self, response):
        user_id = response.meta.get("user_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        s_no = response.meta.get("s_no", "")
        card_num = response.meta.get("card_num", "")
        try:
            self.logger.info(f"开始获取{name}的报名信息")
            zs_id = json.loads(response.text).get("zsID", "") or json.loads(response.text).get("mSN", "")
            if not zs_id:
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                yield result
            else:
                url = f"https://wxxjty.wbs.fit/management/zs/getPrintView?SN={zs_id}"
                if "2025长宁蜀南竹海半程马拉松" in self.race_name:
                    url = f"https://wxxjty.wbs.fit/management/cshcx/getPrintView?SN={zs_id}&ssSN={s_no}&haoma={card_num}&mingzi="
                if "2025“金钻习酒”美丽中国·全民健身跑（海南·海口站）" in self.race_name:
                    url = f"https://wxxjty.wbs.fit/management/mztpl/getPrintView?mSN={zs_id}"
                yield Request(url, callback=self.parse_wbs_raceno, errback=self.err_parse, dont_filter=True,
                              meta={"user_id": user_id, "zs_id": zs_id,
                                    "serial_number": serial_number, "name": name, "card_num": card_num})
        except Exception:
            self.logger.info(f"获取{name}的报名信息错误：{traceback.format_exc()}")

    def parse_wbs_raceno(self, response):
        user_id = response.meta.get("user_id", "")
        zs_id = response.meta.get("zs_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        card_num = response.meta.get("card_num", "")
        proxy_url = response.request.meta.get("proxy", "")
        proxy_pre = response.request.meta.get("proxy_pre", "")
        self.logger.info(f"开始获取{name}号码牌信息")
        try:
            race_no = "".join(response.xpath("//div[@id='u3']//text()").extract()).strip()
            group_name = ""
            if "2025长宁蜀南竹海半程马拉松" in self.race_name:
                race_no = "".join(response.xpath("//div[@id='u9']//text()").extract()).strip()
                group_name = "".join(response.xpath("//div[@id='u7']//text()").extract()).strip()
            if "2025“金钻习酒”美丽中国·全民健身跑（海南·海口站）" in self.race_name:
                race_no = "".join(response.xpath("//div[@id='u10']//text()").extract()).strip()
                group_name = "".join(response.xpath("//div[@id='u9']//text()").extract()).strip()
            if "杭州桐庐半程马拉松" in self.race_name:
                race_area = "".join(response.xpath("//div[@id='u5']//text()").extract()).strip()
                race_no = f"{race_area}{race_no}"
            result_data = {"race_id": self.race_id, "name": name, "user_id": user_id, "race_no": race_no, "runner_status": "",
                           "race_name": self.race_name, "enroll_status": "", "item_name": group_name}

            dir_path = os.path.join(file_path, self.name_first)
            if not os.path.exists(dir_path):
                os.makedirs(dir_path)
            i = 0
            while i < 3:
                try:
                    if "2025长宁蜀南竹海半程马拉松" in self.race_name:
                        url = f"https://wxxjty.wbs.fit/index/index/getcshPage?zsID={zs_id}&haoma={card_num}&xm=&color="
                        img_base64 = SignChrome().get_pic2(url, proxy_url, proxy_pre)
                    else:
                        url = f"https://wxxjty.wbs.fit/index/index/getSaishiCerti?zsID={zs_id}"
                        img_base64 = SignChrome().get_pic(url, dir_path, proxy_url, proxy_pre)
                    image_data = base64.b64decode(img_base64.split(",", 1)[1])
                    pic_name = f'{calc_str_md5(f"{race_no}_{self.race_id}")}.jpg'
                    save_path = os.path.join(dir_path, pic_name)
                    if not os.path.exists(save_path):
                        with open(save_path, "wb") as f:
                            f.write(image_data)
                        upload_path = f"flow/{self.race_id}/{user_id}/raceno/{pic_name}"
                        upload_flag = upload_file(save_path, upload_path)
                        if upload_flag:
                            self.logger.info(f"{save_path}上传成功：{upload_path}")
                        else:
                            self.logger.info(f"{save_path}上传失败：{upload_path}")
                        result_data["race_no_pic"] = upload_path
                    result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data, user_id=user_id)
                    yield result
                    break
                except Exception:
                    i += 1
                    proxy_url = self.get_proxy() if self.use_proxy else ""
            else:
                result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data, user_id=user_id)
                yield result
        except Exception:
            self.logger.info(f"获取{name}的号码牌信息时出错：{traceback.format_exc()}")

    def parse_irunner(self, response):
        user_id = response.meta.get("user_id", "")
        serial_number = response.meta.get("serial_number", "")
        name = response.meta.get("name", "")
        match_eng = response.meta.get("match_eng", "")
        token = response.meta.get("token", "")
        race_flag = response.meta.get("race_flag", False)
        try:
            if not race_flag:
                self.logger.info(f"开始获取{name}的entry_id")
                content = json.loads(response.text).get("entry_info", {})
                if not content:
                    if "授权登录" in response.text:
                        msg = "请先授权登录"
                        result_data = {"msg": msg}
                        result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data, user_id=user_id)
                        yield result
                        current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                        payload = {
                            "msgtype": "text",
                            "text": {
                                "content": f"【登录提醒：{current_time}】\n跑团助手登录过期，需重新登录！",
                                "mentioned_list": ["@all"]
                            }
                        }
                        try:
                            wx_url = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=51e9de35-67d4-4d07-841d-fdeec8fbea3c"
                            requests.post(wx_url, headers={"Content-Type": "text/plain"}, data=json.dumps(payload), timeout=10)
                        except Exception as e:
                            self.logger.error(f"代理异常监控信息发送失败, 原因: {e}")
                        self.close_after_idle = True
                        self.force_to_close_spider = True
                    else:
                        msg = "未查到报名信息"
                        result_data = {"msg": msg}
                        result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data, user_id=user_id)
                        yield result
                else:
                    entry_id = content.get("entry_id", "")
                    body = (
                        "------WebKitFormBoundaryw5lBv8ld8DimAAxW\r\n"
                        'Content-Disposition: form-data; name="entry_id"\r\n\r\n'
                        f"{entry_id}\r\n"
                        "------WebKitFormBoundaryw5lBv8ld8DimAAxW\r\n"
                        'Content-Disposition: form-data; name="access_token"\r\n\r\n'
                        f"{token}\r\n"
                        "------WebKitFormBoundaryw5lBv8ld8DimAAxW--\r\n"
                    ).encode("utf-8")
                    url = f"https://mix-api.irunner.mobi/match/runner-info?match_eng={match_eng}&app_type=&access_token="
                    yield Request(url=url, callback=self.parse_irunner, dont_filter=True, errback=self.err_parse, body=body,
                                  method="POST", headers=self.headers, meta={"user_id": user_id,
                                                                             "name": name, "serial_number": serial_number,
                                                                             "match_eng": match_eng, "race_flag": True})
            else:
                content = json.loads(response.text)
                race_no = content.get("runner_info", {}).get("bib_no", "")
                race_group = content.get("course", {}).get("course_name", "")
                enroll_status = "已中签" if race_no else ""
                runner_status = "已报名" if content.get("runner_info", {}).get("runner_status", "") == "registered" else "报名中"
                result_data = {"race_id": self.race_id, "name": name, "user_id": user_id, "race_no": race_no,
                               "runner_status": runner_status, "race_name": self.race_name, "enroll_status": enroll_status,
                               "item_name": race_group}
                result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data, user_id=user_id)
                yield result
        except Exception:
            self.logger.info(f"获取{name}的entry_id错误：{traceback.format_exc()}")

    def err_parse(self, response):
        try:
            meta = response.request.meta
            self.logger.warning(f"请求失败：{response.request.url},错误原因:{traceback.format_exc()}")
            serial_number = meta.get("serial_number", "")
            user_id = meta.get("user_id", "")
            result = self.send_data(resp=response, serial_number=serial_number, result_data={"msg": "采集失败"},
                                    user_id=user_id)
            yield result
        except:
            pass

    def parse_shuzixindong(self, response):
        try:
            self.logger.info("开始获取图片信息")
            header = response.meta.get("header", {})
            serial_number = response.meta.get("serial_number", "")
            user_id = response.meta.get("user_id", "")
            name = response.meta.get("name", "")
            card_num = response.meta.get("card_num", "")
            img_id = json.loads(response.text).get("data", "")
            yzm_url = f"https://api-changzheng.chinaath.com/changzheng-basic-center-api/api/imageVerify/getVerifyCode?uniqueId={img_id}"
            yield Request(url=yzm_url, callback=self.yzm_parse, headers=header, dont_filter=True,
                          errback=self.err_parse, meta={"header": header, "serial_number": serial_number, "name": name,
                                                        "user_id": user_id, "card_num": card_num, "img_id": img_id})
        except Exception:
            self.logger.error(f"获取图片信息时出错：{traceback.format_exc()}")

    def yzm_parse(self, response):
        try:
            self.logger.info("开始打码")
            header = response.meta.get("header", {})
            serial_number = response.meta.get("serial_number", "")
            user_id = response.meta.get("user_id", "")
            name = response.meta.get("name", "")
            card_num = response.meta.get("card_num", "")
            img_id = response.meta.get("img_id", "")
            ocr = ddddocr.DdddOcr(show_ad=False, beta=True)
            yzm = ocr.classification(response.body)
            r_id = self.shuzixindong_dict.get(self.race_name, "")
            register_data = {"raceId": r_id, "imageUniqueId": img_id, "cardNumber": card_num,
                             "imageVerifyCode": yzm}
            header.update({"Content-Type": "application/json; charset=UTF-8"})
            register_url = "https://api-changzheng.chinaath.com/changzheng-website-center-api/api/website/search/getAppBaseRegisterInfo"
            yield Request(url=register_url, callback=self.register_parse, method="POST", headers=header,
                          errback=self.err_parse, body=json.dumps(register_data), dont_filter=True,
                          meta={"header": header, "serial_number": serial_number, "name": name,
                                "user_id": user_id, "card_num": card_num})
        except Exception:
            self.logger.error(f"打码时出错：{traceback.format_exc()}")

    def register_parse(self, response):
        header = response.meta.get("header", {})
        serial_number = response.meta.get("serial_number", "")
        user_id = response.meta.get("user_id", "")
        name = response.meta.get("name", "")
        card_num = response.meta.get("card_num", "")
        try:
            self.logger.info(f"开始解析{name}报名信息")
            if "验证码错误" in json.loads(response.text).get("msg", ""):
                self.retry_time -= 1
                if self.retry_time > 0:
                    img_url = "https://api-changzheng.chinaath.com/changzheng-basic-center-api/api/imageVerify/getUniqueIdByBusinessType?imageVerifyBusinessType=5"
                    yield Request(url=img_url, callback=self.szxd_img_parse, headers=header, dont_filter=True,
                                  meta={"header": header, "serial_number": serial_number, "name": name,
                                        "user_id": user_id, "card_num": card_num})
                else:
                    result = self.send_data(resp=response, serial_number=serial_number, result_data={"msg": "查询失败，请重试"},
                                            user_id=user_id)
                    yield result
            else:
                register_data = json.loads(response.text).get("data", {})
                if register_data:
                    self.logger.info(f'查询到{name}的参赛号：{register_data.get("entryNumber", "")}')
                    result_data = {"race_id": self.race_id, "name": register_data.get("userName", name),
                                   "user_id": user_id, "race_no": register_data.get("entryNumber", ""),
                                   "runner_status": "", "race_name": register_data.get("raceName", self.race_name),
                                   "enroll_status": "", "item_name": register_data.get("itemName", "")}
                    result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data,
                                            user_id=user_id)
                else:
                    self.logger.info(f'{name}无参赛号')
                    self.logger.info(f'无参赛号时的结果：{response.text}')
                    result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                yield result
        except Exception:
            self.logger.error(f"解析{name}报名信息时出错：{traceback.format_exc()}")

    def parse_diyisaidao(self, response):
        header = response.meta.get("header", {})
        serial_number = response.meta.get("serial_number", "")
        user_id = response.meta.get("user_id", "")
        name = response.meta.get("name", "")
        try:
            code = json.loads(response.text).get("code", 0)
            if code in [200]:
                u_no = json.loads(response.text).get("data", "")
                self.logger.info(f"开始绑定用户：{name},{u_no}")
                if not u_no:
                    self.logger.info(f"绑定用户失败：{name},{json.loads(response.text)}")
                url = "https://matchapi.gusto.cn/api/match/offline/list/my"
                yield Request(url=url, callback=self.parse_race_list, headers=header, dont_filter=True,
                              meta={"header": header, "serial_number": serial_number, "name": name,
                                    "user_id": user_id, "u_no": u_no})
            else:
                self.logger.info(f"绑定用户：{name}时出现问题：{json.loads(response.text)}")
                msg = json.loads(response.text).get("msg", "")
                result_data = {"msg": msg}
                result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data, user_id=user_id)
                yield result
                current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                payload = {
                    "msgtype": "text",
                    "text": {
                        "content": f"【第一赛道：{current_time}】\n[{name}]{msg}！",
                        "mentioned_list": ["@all"]
                    }
                }
                try:
                    wx_url = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=51e9de35-67d4-4d07-841d-fdeec8fbea3c"
                    requests.post(wx_url, headers={"Content-Type": "text/plain"}, data=json.dumps(payload), timeout=10)
                except Exception as e:
                    self.logger.error(f"代理异常监控信息发送失败, 原因: {e}")
                self.close_after_idle = True
                self.force_to_close_spider = True
        except Exception:
            self.logger.error(f"绑定用户：{name}时出错：{traceback.format_exc()}")

    def parse_race_list(self, response):
        header = response.meta.get("header", {})
        serial_number = response.meta.get("serial_number", "")
        user_id = response.meta.get("user_id", "")
        name = response.meta.get("name", "")
        u_no = response.meta.get("u_no", "")
        try:
            self.logger.info("开始解析赛事列表")
            n_list = json.loads(response.text).get("data", {}).get("notEndMatchList", [])
            e_list = json.loads(response.text).get("data", {}).get("endMatchList", [])
            n_list.extend(e_list)
            match_id = ""
            for match in n_list:
                match_name = match.get("matchTitle", "")
                if self.race_name in match_name and name == match.get("username", ""):
                    match_id = "".join(re.findall(r"\/(\d+)\?type=order", match.get("jumpContent", ""))).strip()
                    break
            if match_id:
                url = f"https://matchapi.gusto.cn/api/offline/user/sign/detail?signId={match_id}"
                yield Request(url=url, callback=self.parse_dysdno, headers=header, dont_filter=True,
                              meta={"header": header, "serial_number": serial_number, "name": name,
                                    "user_id": user_id, "u_no": u_no})
            else:
                url = "https://matchapi.gusto.cn/api/user/card/delete"
                result_data = {"msg": "未查到报名信息"}
                yield Request(url=url, method="POST", callback=self.parse_unbind, body=json.dumps({"cardId":u_no}),
                              headers=header, dont_filter=True, errback=self.err_parse,
                              meta={"name": name, "result_data": result_data, "serial_number": serial_number,
                                    "user_id": user_id, "u_no": u_no, "header": header})
        except Exception:
            self.logger.error(f"绑定用户：{name}时出错：{traceback.format_exc()}")

    def parse_dysdno(self, response):
        header = response.meta.get("header", {})
        serial_number = response.meta.get("serial_number", "")
        user_id = response.meta.get("user_id", "")
        name = response.meta.get("name", "")
        u_no = response.meta.get("u_no", "")
        try:
            self.logger.info(f"开始解析{name}的参赛号信息")
            register_data = json.loads(response.text).get("data", {})
            if register_data:
                result_data = {"race_id": self.race_id, "name": register_data.get("username", name),
                               "user_id": user_id, "race_no": register_data.get("fullBibno", ""),
                               "runner_status": "", "race_name": register_data.get("raceName", self.race_name),
                               "enroll_status": "", "item_name": register_data.get("projectName", "")}
            else:
                result_data = {"msg": "未查到报名信息"}
            url = "https://matchapi.gusto.cn/api/user/card/delete"
            yield Request(url=url, method="POST", callback=self.parse_unbind, body=json.dumps({"cardId":u_no}),
                          headers=header, dont_filter=True, errback=self.err_parse,
                          meta={"name": name, "result_data": result_data, "serial_number": serial_number,
                                "user_id": user_id, "u_no": u_no, "header": header})
        except Exception:
            self.logger.error(f"解析报名信息时出错：{traceback.format_exc()}")

    def parse_unbind(self, response):
        header = response.meta.get("header", {})
        name = response.meta.get("name", "")
        serial_number = response.meta.get("serial_number", "")
        user_id = response.meta.get("user_id", "")
        u_no = response.meta.get("u_no", "")
        result_data = response.meta.get("result_data", {})
        try:
            self.logger.info(f"开始解绑{name},{u_no}")
            code = json.loads(response.text).get("code", 0)
            if code == 200:
                self.logger.info(f"解绑{name}成功,{u_no}")
            else:
                self.logger.info(f"解绑{name}失败,{json.loads(response.text)}")
            self.logger.info(f"{name}的参赛号信息：{result_data}")
            result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data,
                                    user_id=user_id)
            yield result
            if self.user_list:
                user = self.user_list.pop(0)
                serial_number = user.get("serialNumber", "")
                name = user.get("name", "")
                user_id = user.get("user_id", "")
                card_num = user.get("card_num", "")
                if int(card_num[-2:-1]) % 2 == 0:
                    sex = 2
                else:
                    sex = 1
                data = {"me": False, "realName": name, "pinyin": "ZHANG SAN", "sex": sex, "cardType": 1,
                        "cardNumber": card_num, "birthday": 846633600000, "country": "中国", "province": "北京市",
                        "city": "北京市", "area": "东城区", "address": "东大街234号", "mobile": "18721453548",
                        "email": "dasda@163.com", "size": "L", "emergencyContact": "李四",
                        "emergencyContactMobile": "18912357461", "bloodType": 1}

                url = "https://matchapi.gusto.cn/api/user/card/create"
                yield Request(url=url, method="POST", callback=self.parse_diyisaidao, body=json.dumps(data),
                              headers=header, dont_filter=True, errback=self.err_parse,
                              meta={"header": header, "serial_number": serial_number, "user_id": user_id,
                                    "name": name})
        except Exception:
            self.logger.error(f"解绑{name}时出错：{traceback.format_exc()}")

    def parse_malamala(self, response):
        try:
            header = response.meta.get("header", {})
            serial_number = response.meta.get("serial_number", "")
            user_id = response.meta.get("user_id", "")
            name = response.meta.get("name", "")
            card_num = response.meta.get("card_num", "")
            self.logger.info("开始获取验证码链接")
            data = json.loads(response.text)
            img_url = data.get("image", "")
            session_id = data.get("sessionID", "")
            yield Request(url=img_url, callback=self.mlml_yzm_parse, headers=header, dont_filter=True,
                          meta={"header": header, "serial_number": serial_number, "name": name,
                                "user_id": user_id, "card_num": card_num, "session_id": session_id})
        except Exception:
            self.logger.error(f"验证实名时出错：{traceback.format_exc()}")

    def mlml_yzm_parse(self, response):
        try:
            self.logger.info("开始打码")
            header = response.meta.get("header", {})
            serial_number = response.meta.get("serial_number", "")
            user_id = response.meta.get("user_id", "")
            name = response.meta.get("name", "")
            card_num = response.meta.get("card_num", "")
            session_id = response.meta.get("session_id", "")
            ocr = ddddocr.DdddOcr(show_ad=False, beta=True)
            yzm = ocr.classification(response.body)
            r_id = self.malamala_dict.get(self.race_name, "")
            url = f"https://user-gw.mararun.com/v2/matchH5/search?identityCard={card_num}&matchID={r_id}&code={yzm}&sessionID={session_id}"
            yield Request(url=url, callback=self.parse_malamala_raceno, headers=header,
                          errback=self.err_parse, dont_filter=True,
                          meta={"header": header, "serial_number": serial_number, "name": name,
                                "user_id": user_id, "card_num": card_num})
        except Exception:
            self.logger.error(f"打码时出错：{traceback.format_exc()}")

    def parse_malamala_raceno(self, response):
        header = response.meta.get("header", {})
        serial_number = response.meta.get("serial_number", "")
        user_id = response.meta.get("user_id", "")
        name = response.meta.get("name", "")
        try:
            self.logger.info(f"开始解析{name}的参赛号信息")
            register_data = json.loads(response.text).get("data", {})
            if register_data:
                result_data = {"race_id": self.race_id, "name": register_data.get("pName", name),
                               "user_id": user_id, "race_no": register_data.get("CNO", ""),
                               "runner_status": "", "race_name": register_data.get("matchName", self.race_name),
                               "enroll_status": "", "item_name": register_data.get("matchEventName", "")}
                result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data,
                                        user_id=user_id)
            else:
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
            yield result
        except Exception:
            self.logger.error(f"解析报名信息时出错：{traceback.format_exc()}")

    def parse_cgts(self, response):
        serial_number = response.meta.get("serial_number", "")
        user_id = response.meta.get("user_id", "")
        name = response.meta.get("name", "")
        try:
            self.logger.info(f"开始解析{name}的参赛号信息")
            data_list = json.loads(response.text).get("data", {}).get("records", [])
            if data_list:
                for data in data_list:
                    if self.race_name in data.get("gameName", ""):
                        result_data = {"race_id": self.race_id, "name": data.get("name", name),
                                       "user_id": user_id, "race_no": data.get("no", ""),
                                       "runner_status": "", "race_name": data.get("gameName", self.race_name),
                                       "enroll_status": "", "item_name": data.get("packageName", "")}
                        no_url = data.get("noImg", "")
                        if no_url:
                            yield Request(no_url, callback=self.parse_pic, errback=self.err_parse, dont_filter=True,
                                          meta={"user_id": user_id, "serial_number": serial_number,
                                                "name": name, "result_data": result_data})
                        else:
                            result = self.send_data(resp=response, serial_number=serial_number, result_data=result_data,
                                                    user_id=user_id)
                            yield result
                        break
            else:
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                yield result
        except Exception:
            self.logger.error(f"解析报名信息时出错：{traceback.format_exc()}")

    def parse_saye(self, response):
        serial_number = response.meta.get("serial_number", "")
        user_id = response.meta.get("user_id", "")
        name = response.meta.get("name", "")
        try:
            self.logger.info(f"开始解析{name}的参赛号信息")
            data_list = json.loads(response.text).get("data", {}).get("data", [])
            if data_list:
                race_list = []
                for data in data_list:
                    result_data = {"race_id": self.race_id, "name": data.get("name", name),
                                   "user_id": user_id, "race_no": data.get("code", ""),
                                   "runner_status": "", "race_name": data.get("project_name", self.race_name),
                                   "enroll_status": "", "item_name": data.get("group", "")}
                    race_list.append(result_data)
                result = self.send_data(resp=response, serial_number=serial_number, result_data=race_list,
                                        user_id=user_id)
                yield result
            else:
                result = self.send_data(resp=response, serial_number=serial_number, user_id=user_id)
                yield result
        except Exception:
            self.logger.error(f"解析报名信息时出错：{traceback.format_exc()}")

    def get_proxy(self):
        url = "http://api.dmdaili.com/dmgetip.asp?apikey=062c68ee&pwd=2ceacf762585db3e1d24cbdb4ef11091&getnum=1&httptype=1&geshi=2&fenge=&fengefu=&operate=all"
        content = requests.get(url).text
        ip = json.loads(content).get("data", [])[0].get("ip", "")
        port = json.loads(content).get("data", [])[0].get("port", "")
        proxy = f"http://{ip}:{port}"
        return proxy

    def send_data(self, resp=None, serial_number=None, result_data=None, user_id=None):
        if result_data is None:
            result_data = {"msg": "未查到报名信息"}
        result_dict = {"serialNumber": serial_number, "webType": self.name_first,
                       "userId": user_id, "raceId": self.race_id, "code": 200,
                       "crawlerType": self.name_second, "data": str(result_data)}
        result = self.result_item_assembler(resp)
        result['result_data'] = result_dict
        return result

    def decryptDes(self, des_key, data):
        key = des_key.encode('utf-8')
        if len(key) != 8:
            key = key.ljust(8, b'\0')[:8]
        ciphertext = bytes.fromhex(data)
        cipher = DES.new(key, DES.MODE_ECB)
        decrypted_data = cipher.decrypt(ciphertext)
        plaintext = unpad(decrypted_data, DES.block_size)
        return plaintext.decode('utf-8')

    def encryptDes(self, des_key, data):
        key = des_key.encode('utf-8')
        if len(key) != 8:
            key = key.ljust(8, b'\0')[:8]
        plaintext = data.encode('utf-8')
        cipher = DES.new(key, DES.MODE_ECB)
        padded_data = pad(plaintext, DES.block_size)
        encrypted_data = cipher.encrypt(padded_data)
        ciphertext_hex = binascii.hexlify(encrypted_data).decode('utf-8')
        return ciphertext_hex